You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord.js v14.2.0选择菜单选项数量超限报错求助

问题原因

Discord官方API明确规定,字符串选择菜单(StringSelectMenu)的选项数量上限为25个。你碰到的Expected: expected <= 25,Received:35报错,就是因为部分服务器的角色总数超过了25,而你的代码把所有角色都塞进了选择菜单,触发了discord.js依赖的@sapphire/shapeshift验证库的数值校验。

从报错栈也能看出来,错误是在SelectMenuBuilder.addOptions调用时触发的,完全符合这个限制逻辑。

解决办法

1. 过滤掉不必要的角色

优先排除不需要展示的角色,比如默认的@everyone、机器人托管的角色,直接减少选项数量:

const listedRoles = [];
interaction.guild.roles.cache.forEach(role => {
    // 排除@everyone和机器人自动创建的角色
    if (!role.managed && role.id !== interaction.guild.id) {
        listedRoles.push({
            label: role.name,
            description: "Use this role.",
            emoji: "➕",
            value: role.id
        })
    }
}); 

2. 强制限制选项数量为25个

如果不需要过滤角色,直接截断数组只保留前25个选项:

const listedRoles = [];
interaction.guild.roles.cache.forEach(role => { 
    listedRoles.push({
        label: role.name,
        description: "Use this role.",
        emoji: "➕",
        value: role.id
    })
}); 

// 只取前25个角色选项
const limitedRoles = listedRoles.slice(0, 25);

const row = new ActionRowBuilder().addComponents(
    new SelectMenuBuilder()
    .setCustomId("RoleMenu")
    .setPlaceholder("Select a role.")
    .addOptions(limitedRoles)    
)

3. 实现分页选择菜单

如果必须展示所有角色,可以做分页逻辑,用按钮切换分页,每次只显示25个选项:

const listedRoles = [];
interaction.guild.roles.cache.forEach(role => { 
    listedRoles.push({
        label: role.name,
        description: "Use this role.",
        emoji: "➕",
        value: role.id
    })
}); 

// 分页配置
const pageSize = 25;
const totalPages = Math.ceil(listedRoles.length / pageSize);
let currentPage = 0;

// 获取当前页的角色选项
const getCurrentPageOptions = () => {
    const start = currentPage * pageSize;
    return listedRoles.slice(start, start + pageSize);
};

// 生成带分页按钮的行
const paginationRow = new ActionRowBuilder().addComponents(
    new ButtonBuilder()
        .setCustomId("prevPage")
        .setLabel("上一页")
        .setStyle(ButtonStyle.Primary)
        .setDisabled(currentPage === 0),
    new ButtonBuilder()
        .setCustomId("nextPage")
        .setLabel("下一页")
        .setStyle(ButtonStyle.Primary)
        .setDisabled(currentPage === totalPages - 1)
);

// 初始选择菜单行
const selectRow = new ActionRowBuilder().addComponents(
    new SelectMenuBuilder()
    .setCustomId("RoleMenu")
    .setPlaceholder(`第${currentPage+1}/${totalPages}页 - 选择角色`)
    .addOptions(getCurrentPageOptions())    
);

// 发送消息,包含选择菜单和分页按钮
await interaction.reply({ components: [selectRow, paginationRow] });

// 后续需要监听按钮点击事件,更新currentPage并重新编辑消息的选择菜单...

内容的提问来源于stack exchange,提问作者ri1_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 17:07:38