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

Discord.js v13开发机器人遭遇TypeError: Cannot read properties of undefined (reading 'set')错误,请求排查

问题分析与解决

你遇到的TypeError: Cannot read properties of undefined (reading 'set')错误,核心原因很明确:client.slash这个属性根本没被初始化,它默认是undefined,自然没法调用set方法。

为什么会出现这个问题?

看你贴的代码,你直接在client.slash.set(pull.name, pull)这一行调用了set方法,但从始至终都没有在client对象上创建slash这个存储命令的集合。JavaScript里访问一个不存在的对象属性会返回undefined,对undefined调用方法就会抛出这个错误。

解决步骤

1. 初始化client.slash为Discord.js Collection

Discord.js提供了Collection类(类似Map,但更适合存储命令这类键值对数据),我们需要先给client添加这个属性。有两种方式可以做到:

方式一:在主文件(index.js)中初始化

如果你是在index.js里创建的Discord客户端,直接在创建client后添加这一行:

const { Client, Collection, GatewayIntentBits } = require('discord.js');
// 注意:v13+需要指定intents,根据你的机器人需求调整
const client = new Client({ intents: [GatewayIntentBits.Guilds] });

// 初始化slash命令集合
client.slash = new Collection();

// 然后再加载你的slash模块
require('./structures/slash.js')(client);

client.login('你的机器人令牌');
方式二:在slash.js模块内部初始化

如果不想修改主文件,也可以在slash.js的模块开头先导入Collection,然后在函数内部检查并初始化:

let slash = []
const { readdirSync } = require("fs");
const { Collection } = require("discord.js"); // 导入Collection
const ascii = require("ascii-table");
let table = new ascii("Slash Commands");
table.setHeading('Slash Command', ' Load status');

module.exports = (client) => {
  // 初始化client.slash,如果它还不存在的话
  if (!client.slash) {
    client.slash = new Collection();
  }

  readdirSync("./Slash/").forEach(dir => {
    const commands = readdirSync(`./Slash/${dir}/`).filter(file => file.endsWith(".js"));
    for (let file of commands) {
      let pull = require(`../Slash/${dir}/${file}`);
      if (pull.name) {
        client.slash.set(pull.name, pull); // 现在client.slash存在了,不会报错
        slash.push(pull);
        table.addRow(file, '✔️ -> Loaded Slash Command');
      } else {
        table.addRow(file, `❌ -> missing a name property, or name is not a string.`);
        continue;
      }
    }
  });
  console.log(table.toString());
  
  client.on("ready",async ()=> {
    await client.guilds.cache.get('839096342953328691').commands.set(slash);
  })
}

2. 额外注意:确保ready事件能正确触发

如果你的主文件是先调用client.login()再加载slash模块,那么ready事件可能已经触发过了,导致命令注册的代码没执行。所以要确保先加载所有模块,再调用client.login()。

修改后的完整slash.js示例

let slash = []
const { readdirSync } = require("fs");
const { Collection } = require("discord.js");
const ascii = require("ascii-table");
let table = new ascii("Slash Commands");
table.setHeading('Slash Command', ' Load status');

module.exports = (client) => {
  // 初始化slash命令集合,兼容已存在的情况
  client.slash = client.slash || new Collection();

  readdirSync("./Slash/").forEach(dir => {
    const commands = readdirSync(`./Slash/${dir}/`).filter(file => file.endsWith(".js"));
    for (let file of commands) {
      let pull = require(`../Slash/${dir}/${file}`);
      if (pull.name) {
        client.slash.set(pull.name, pull);
        slash.push(pull);
        table.addRow(file, '✔️ -> Loaded Slash Command');
      } else {
        table.addRow(file, `❌ -> missing a name property, or name is not a string.`);
        continue;
      }
    }
  });
  console.log(table.toString());
  
  // 用once替代on,避免重复注册命令
  client.once("ready",async ()=> {
    const targetGuild = client.guilds.cache.get('839096342953328691');
    if (!targetGuild) {
      console.error('无法找到目标服务器,请检查服务器ID是否正确');
      return;
    }
    await targetGuild.commands.set(slash);
    console.log('Slash命令已成功注册到目标服务器');
  })
}

我还帮你优化了两处细节:把client.on("ready")改成client.once("ready"),避免机器人重新登录时重复注册命令;另外加了服务器不存在的判断,防止后续出现新的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 20:12:49