Discord.js v13发送非空消息触发"Cannot send empty message"错误
问题描述
在Discord.js v13中发送消息时触发DiscordAPIError: Cannot send an empty message错误,对应发送代码如下:
const startMessage = await channel.send({ content: `Quest: **${start.string} ${currentGame.startMessage.toLowerCase()}** *(You have ${Math.floor(actualTime / 1000)} seconds)*`})
关键现象:
- 仅在
channel.send()前添加await时出现该错误 - 消息实际已发送成功,但仍会触发错误
- 调试显示请求中的
content字段为undefined
核心代码片段:
module.exports.runGame = async function (channel, players_, client) { let players = players_ let time = 1 let winners let gameOn = true let rounds = 1 let lastGame = null let config = JSON.parse(fs.readFileSync(`./guilds/${channel.guild.id}.json`)); while (gameOn) { let enabledGames = [] for(let game of minigames){ if(config.minigames[game.name]){ if(game.name == 'oppositeDay' && rounds < 4) continue enabledGames.push(game) } } if(enabledGames.length == 0){ channel.send('You need to have at least one game enabled to play. Enable/disable with the config command.') return } let currentGame = enabledGames[getRandomInt(enabledGames.length)] while(currentGame == lastGame){ currentGame = enabledGames[getRandomInt(enabledGames.length)] } let start if (currentGame.name == 'oppositeDay') { start = { string: config.opposite_day ? 'Good morning,' : 'Simon says', real: true } } else if(rounds < 3){ start = { string: 'Simon says', real: true } } else { start = randomStart(channel.guild.id, config) } let actualTime = (time * currentGame.defTime).clamp(5000, 15000) console.log("\n\n\n\n\n\n\n\n\nSTART\n\n\n\n\n"); try { const startMessage = await channel.send({ content: `Quest: **${start.string} ${currentGame.startMessage.toLowerCase()}** *(You have ${Math.floor(actualTime / 1000)} seconds)*`}) } catch (err) { console.log(`Known Error in line 59 on game.js ${err}`) } console.log("\n\n\n\n\n\n\n\n\nEND\n\n\n\n\n"); console.log(currentGame.name) let { playersOut, playersLeft, configOut } = await currentGame.run(channel, players, actualTime, client, { simonSaid: start.real, startMessage: startMessage, config: config }) config = configOut } }
完整错误栈:
START /home/lixt/Desktop/The Lixt Bot/LIXTON/node_modules/discord.js/src/rest/RequestHandler.js:298 throw new DiscordAPIError(data, res.status, request); ^ DiscordAPIError: Cannot send an empty message at RequestHandler.execute (/home/lixt/Desktop/The Lixt Bot/LIXTON/node_modules/discord.js/src/rest/RequestHandler.js:298:13) at processTicksAndRejections (node:internal/process/task_queues:96:5) at async RequestHandler.push (/home/lixt/Desktop/The Lixt Bot/LIXTON/node_modules/discord.js/src/rest/RequestHandler.js:50:14) at async TextChannel.send (/home/lixt/Desktop/The Lixt Bot/LIXTON/node_modules/discord.js/src/structures/interfaces/TextBasedChannel.js:171:15) { method: 'post', path: '/channels/997996030572384288/messages', code: 50006, httpStatus: 400, requestData: { json: { content: undefined, tts: false, nonce: undefined, embeds: undefined, components: undefined, username: undefined, avatar_url: undefined, allowed_mentions: undefined, flags: undefined, message_reference: undefined, attachments: undefined, sticker_ids: undefined }, files: [] } }
解决方案
1. 排查核心变量有效性
错误栈显示content为undefined,说明模板字符串中的某个变量为空或未定义:
- 检查
randomStart函数返回值:该函数可能未返回包含string属性的对象,或返回了undefined - 检查小游戏配置:部分启用的
minigames对象可能缺失startMessage字段,调用toLowerCase()时会报错,导致整个模板字符串失效
2. 添加变量校验逻辑
在发送消息前先校验关键变量,避免生成无效的content:
try { // 校验必要变量是否存在 if (!start?.string || !currentGame?.startMessage) { console.warn('游戏指令生成失败,缺少必要变量:', { startString: start?.string, gameMessage: currentGame?.startMessage }); await channel.send('本轮游戏指令生成失败,请重试'); continue; } // 单独生成content变量,便于调试 const content = `Quest: **${start.string} ${currentGame.startMessage.toLowerCase()}** *(You have ${Math.floor(actualTime / 1000)} seconds)*`; const startMessage = await channel.send({ content }); } catch (err) { console.log(`游戏消息发送错误: ${err}`) }
3. 修复randomStart函数返回值
确保randomStart始终返回包含string和real属性的有效对象,避免返回空值:
function randomStart(guildId, config) { const options = [ { string: 'Simon says', real: true }, { string: 'Do', real: false } ]; const choice = options[getRandomInt(options.length)]; // 兜底确保string不为空 return choice.string ? choice : { string: 'Do', real: false }; }
4. 检查所有小游戏配置
确认所有启用的小游戏对象都包含startMessage字段,避免因属性缺失导致报错。
内容的提问来源于stack exchange,提问作者Lixt
相关产品推荐
相关产品推荐

