discord.js调用commands.set()注册斜杠命令报错求解
问题原因
- 报错本质是传参类型错误,和discord.js依赖本身的代码无关,不需要修改node_modules内的文件。
GuildApplicationCommandManager.set()方法设计为全量覆盖指定服务器下的所有斜杠命令,第一个参数要求传入命令配置构成的数组,内部会对数组调用.map()做格式转换。你传入的是单个命令对象,普通对象不存在.map()方法,因此抛出TypeError: commands.map is not a function。 - 你写的命令配置本身存在多处不符合Discord API规则的问题,就算修正传参类型也无法正常注册:
- 选项列表字段名错误:应为
options,不是option - 必填项标识字段名错误:应为
required,不是require - 选项
type字段传值错误:discord.js不接受字符串格式的类型值(如"USER""STRING"),需要传入官方定义的枚举值或对应数值编码 - 命令名、选项名不符合Discord规则:必须为全小写、无空格的格式,你写的
UTENTE/MOTIVO大写命名会被API直接拒绝
- 选项列表字段名错误:应为
- 方法选择不当:如果只是想新增/更新单个ban命令,不需要用全量覆盖的
.set(),否则会清空该服务器下所有其他已注册的斜杠命令,用.create()方法更安全。
修复方案
首先在文件顶部引入discord.js的选项类型枚举:
const { Client, GatewayIntentBits, ApplicationCommandOptionType } = require('discord.js');
方案1:仅注册/更新单个ban命令(推荐)
替换原有注册逻辑,使用.create()方法提交单个命令,同时修正所有配置错误:
client.on('messageCreate', async (message) =>{ if(message.content.toLowerCase() === "lava.register"){ const commandData = { name: "ban", description: "Banna un utente dal server", options: [ { name: "utente", description: "Specifica l'utente da bannare dal server", type: ApplicationCommandOptionType.User, required: true, }, { name: "motivo", description: "Specifica il motivo del ban", type: ApplicationCommandOptionType.String, required: true, } ] }; const guild = client.guilds.cache.get('957317299289858108'); if (!guild) return message.reply('未找到目标服务器'); const comando = await guild.commands.create(commandData); console.log('命令注册成功:', comando) message.reply('ban命令注册完成') } })
方案2:需要全量覆盖服务器下所有斜杠命令
如果确实要重置该服务器的所有斜杠命令,把命令配置放到数组中再传给.set()方法,注意需要保留的其他命令也要一并写入数组,否则会被直接删除:
client.on('messageCreate', async (message) =>{ if(message.content.toLowerCase() === "lava.register"){ // 所有要保留的命令都放在这个数组里 const allCommands = [ { name: "ban", description: "Banna un utente dal server", options: [ { name: "utente", description: "Specifica l'utente da bannare dal server", type: ApplicationCommandOptionType.User, required: true, }, { name: "motivo", description: "Specifica il motivo del ban", type: ApplicationCommandOptionType.String, required: true, } ] } ]; const guild = client.guilds.cache.get('957317299289858108'); if (!guild) return message.reply('未找到目标服务器'); const comando = await guild.commands.set(allCommands); console.log('命令全量覆盖完成:', comando) message.reply('所有斜杠命令已更新') } })
注意事项
- 斜杠命令注册是持久化操作,注册成功后会一直保存在Discord服务器端,不需要每次触发消息事件都重复调用注册接口,频繁请求会触发Discord API速率限制。建议将命令注册逻辑单独抽成部署脚本,机器人启动时执行一次即可。
- 如果使用discord.js v13版本,
ApplicationCommandOptionType的引入路径为discord-api-types/v10,枚举值对应关系不变。
内容的提问来源于stack exchange,提问作者YI HAN ZHOU
相关产品推荐
相关产品推荐

