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_
相关产品推荐
相关产品推荐

