Discord.js V14创建无options斜杠命令遇50035错误求解决
问题:Discord.js V14 创建无options斜杠命令时触发LIST_TYPE_CONVERT错误
我在Discord.js V14版本创建斜杠命令时,遇到了如下错误:
DiscordAPIError[50035]: Invalid Form Body
0[LIST_TYPE_CONVERT]: Only iterables may be used in a ListType
我要做的ping是个基础命令,不需要添加任何options属性。
相关代码
ping.js
module.exports = { name: "ping", description: "View the reaction times", slashInfo: { enabled: true, public: false, }, getSlashInfo: function() { const { SlashCommandBuilder } = require("discord.js"); const builder = new SlashCommandBuilder(); // 设置基础命令信息 builder.setName(this.name); builder.setDescription(this.description); // 允许在DM中使用 builder.setDMPermission(true); // 返回JSON格式的命令数据 return builder.toJSON(); }, async execute(interaction, _prefix, client) { interaction.reply({ content: `**Pong** in ${client.ws.ping}ms` }); } }
commandHandler.js
function postSlashCommand(data, to, client) { if (!to) { // 向所有服务器推送命令 rest.put( Routes.applicationCommands(client.user.id), { body: data } ); } else { // 仅向指定服务器推送命令 rest.put( Routes.applicationGuildCommands(client.user.id, to), { body: data } ); } } async function setupSlashCommands(directory, client) { // 遍历命令文件夹 const commandFolders = fs.readdirSync(`./${directory}`).filter(file => !file.endsWith(".js") && !file.endsWith(".json")); for (const folder of commandFolders) { const commandFiles = fs.readdirSync(`./${directory}/${folder}`).filter(file => file.endsWith(".js")); for (const file of commandFiles) { // 获取命令对象 const command = require(`../../${directory}/${folder}/${file}`); // 跳过不支持斜杠命令的文件 if (!command.slashInfo?.enabled) return; // 获取斜杠命令数据 let data = command.getSlashInfo(); // 推送命令到Discord if (command.slashInfo.public) { // 推送全局命令 postSlashCommand(data, null, client); } else { // 推送测试服务器命令 postSlashCommand(data, require("../../utils/config.json").DevServer, client); } } } } module.exports = (client) => setupSlashCommands("commands", client);
完整错误信息
throw new DiscordAPIError.DiscordAPIError(data, "code" in data ? data.code : data.error, status, method, url, requestData); ^ DiscordAPIError[50035]: Invalid Form Body 0[LIST_TYPE_CONVERT]: Only iterables may be used in a ListType at SequentialHandler.runRequest (D:\Projects\...\node_modules\@discordjs\rest\dist\lib\handlers\SequentialHandler.cjs:287:15) at processTicksAndRejections (node:internal/process/task_queues:96:5) at async SequentialHandler.queueRequest (D:\Projects\...\node_modules\@discordjs\rest\dist\lib\handlers\SequentialHandler.cjs:99:14) at async REST.request (D:\Projects\...\node_modules\@discordjs\rest\dist\lib\REST.cjs:52:22) { rawError: { code: 50035, errors: { _errors: [ { code: 'LIST_TYPE_CONVERT', message: 'Only iterables may be used in a ListType' } ] }, message: 'Invalid Form Body' }, code: 50035, status: 400, method: 'PUT', url: 'https://discord.com/api/v10/applications/<application_id>/guilds/<guild_id>/commands', requestBody: { files: undefined, json: { options: [], name: 'ping', name_localizations: undefined, description: 'View the reaction times', description_localizations: undefined, default_permission: undefined, default_member_permissions: undefined, dm_permission: true } } }
解答
当然可以创建不带options属性的斜杠命令,问题出在命令注册的格式错误,而非命令本身。
Discord API的批量注册接口要求接收命令数组——哪怕只有一个命令,也必须用数组包裹。但你的postSlashCommand函数直接把单个命令的JSON对象传给了body参数,API会把这个对象当成要遍历的列表,因此触发了LIST_TYPE_CONVERT错误。
修复方案1:修改postSlashCommand函数
将单个命令包装成数组后再发送:
function postSlashCommand(data, to, client) { // 确保传入的是数组,单个命令则包裹成数组 const bodyData = Array.isArray(data) ? data : [data]; if (!to) { rest.put( Routes.applicationCommands(client.user.id), { body: bodyData } ); } else { rest.put( Routes.applicationGuildCommands(client.user.id, to), { body: bodyData } ); } }
修复方案2:批量收集命令后提交(更高效)
一次性收集所有命令数据,再批量提交,减少API请求次数:
async function setupSlashCommands(directory, client) { const globalCommands = []; const guildCommands = []; const devServerId = require("../../utils/config.json").DevServer; const commandFolders = fs.readdirSync(`./${directory}`).filter(file => !file.endsWith(".js") && !file.endsWith(".json")); for (const folder of commandFolders) { const commandFiles = fs.readdirSync(`./${directory}/${folder}`).filter(file => file.endsWith(".js")); for (const file of commandFiles) { const command = require(`../../${directory}/${folder}/${file}`); // 跳过不支持斜杠的命令,用continue而非return,避免终止整个循环 if (!command.slashInfo?.enabled) continue; const data = command.getSlashInfo(); if (command.slashInfo.public) { globalCommands.push(data); } else { guildCommands.push(data); } } } // 提交全局命令 if (globalCommands.length > 0) { await rest.put(Routes.applicationCommands(client.user.id), { body: globalCommands }); } // 提交测试服务器命令 if (guildCommands.length > 0) { await rest.put(Routes.applicationGuildCommands(client.user.id, devServerId), { body: guildCommands }); } }
另外注意原代码中的if (!command.slashInfo?.enabled) return;,这会导致遍历到第一个不支持斜杠的命令时直接终止整个循环,改成continue才能继续处理其他命令。
修改完成后,无options的ping命令即可正常注册。
内容的提问来源于stack exchange,提问作者Tyler2P
相关产品推荐
相关产品推荐

