Search code examples
node.jsdiscorddiscord.js

Discord.js v14 - TypeError: Cannot read properties of undefined (reading 'commands')


I've been building a discord.js bot recently to brush up on my javascript as it's been a while. Been following a guide on a commands & events reload slash command however it's coming up with the following error:

TypeError: Cannot read properties of undefined (reading 'commands')
    at loadCommands (/home/runner/tester/handlers/commandHandler.js:19:14)
    at Object.execute (/home/runner/tester/commands/owner/reload.js:33:11)
    at Client.<anonymous> (/home/runner/tester/index.js:58:17)
    at Client.emit (node:events:513:28)
    at Client.emit (node:domain:489:12)
    at InteractionCreateAction.handle (/home/runner/tester/node_modules/discord.js/src/client/actions/InteractionCreate.js:97:12)
    at module.exports [as INTERACTION_CREATE] (/home/runner/tester/node_modules/discord.js/src/client/websocket/handlers/INTERACTION_CREATE.js:4:36)
    at WebSocketManager.handlePacket (/home/runner/tester/node_modules/discord.js/src/client/websocket/WebSocketManager.js:352:31)
    at WebSocketShard.onPacket (/home/runner/tester/node_modules/discord.js/src/client/websocket/WebSocketShard.js:494:22)

As for the code it's reffering to:

commandHandler.js:

function loadCommands(client) {
  const ascii = require("ascii-table");
  const fs = require("fs");
  const table = new ascii().setHeading("File Name", "Status");
  require("colors");

  let commandsArray = [];

  const commandsFolder = fs.readdirSync("./commands");
  for (const folder of commandsFolder) {
    const commandFiles = fs
      .readdirSync(`./commands/${folder}`)
      .filter((file) => file.endsWith(".js"));

    for (const file of commandFiles) {
      const commandFile = require(`../commands/${folder}/${file}`);

      const properties = { folder, ...commandFile };
      client.commands.set(commandFile.data.name, properties);

      commandsArray.push(commandFile.data.toJSON());

      table.addRow(file, "Loaded");
      continue;
    }
  }

  client.application.commands.set(commandsArray);

  return console.log(table.toString(), "\n[+]".green + " Loaded Commands");
}

module.exports = { loadCommands };

reload.js:

const { Client, SlashCommandBuilder, EmbedBuilder } = require("discord.js");
const { loadCommands } = require("../../handlers/commandHandler");
const { loadEvents } = require("../../handlers/eventHandler");

module.exports = {
  data: new SlashCommandBuilder()
  .setName('reload')
  .setDescription('Reload your commands or events.')
  .addSubcommand(subcommand =>
  subcommand.setName('commands')
  .setDescription('Reload your commands.')
  )
    .addSubcommand(subcommand =>
      subcommand.setName('events')
      .setDescription('Reload your events.')
      ),

    async execute(interaction, client) {
      const { user } = interaction;
      if (user.id !== "217414221728710656") return interaction.reply({
        embeds: [new EmbedBuilder()
        .setColor('#2f3136')
        .setDescription('This command is only for the bot developer!')], ephemeral: true
      })

      const sub = interaction.options.getSubcommand()
      const embed = new EmbedBuilder()
      .setTitle('Developer')
      .setColor('#2f3136')

      switch (sub) {
        case "commands": {
          loadCommands(client)
          interaction.reply({ embeds: [embed.setDescription('Commands reloaded!')] })
          console.log(`${user} has reloaded the bot commands.`)
        }
        break;
        case "events": {
          loadEvents(client)
          interaction.reply({ embeds: [embed.setDescription('Events reloaded!')] })
          console.log(`${user} has reloaded the bot events.`)
        }
        break;
        }
    }
}

index.js:

const { Client, Collection, Events, GatewayIntentBits, Partials, ActivityType } = require('discord.js');
require("colors");

const fs = require('node:fs');
const path = require('node:path');
const { token } = require('./config.json');

const client = new Client({ intents: [GatewayIntentBits.Guilds] });

client.commands = new Collection();

const foldersPath = path.join(__dirname, 'commands');
const commandFolders = fs.readdirSync(foldersPath);

for (const folder of commandFolders) {
    const commandsPath = path.join(foldersPath, folder);
    const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
    for (const file of commandFiles) {
        const filePath = path.join(commandsPath, file);
        const command = require(filePath);
        if ('data' in command && 'execute' in command) {
            client.commands.set(command.data.name, command);
        } else {
            console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`);
        }
    }
}

const eventsPath = path.join(__dirname, 'events');
const eventFiles = fs.readdirSync(eventsPath).filter(file => file.endsWith('.js'));

for (const file of eventFiles) {
    const filePath = path.join(eventsPath, file);
    const event = require(filePath);
    if (event.once) {
        client.once(event.name, (...args) => event.execute(...args));
    } else {
        client.on(event.name, (...args) => event.execute(...args));
    }
}

const { loadCommands } = require("./handlers/commandHandler.js");
const { loadEvents } = require("./handlers/eventHandler.js");

client.once(Events.ClientReady, () => {
  console.log(`--------------------------------------------------------`)
  console.log("ඞ".red + " sus")
  console.log(`--------------------------------------------------------`)
                                            
  console.log(
    `Logged in as: ${client.user.tag.green} |`, `User ID: ${client.user.id.green}`,
  );
  client.user.setActivity("Duck ASMR", {type: ActivityType.Streaming, url: "https://www.twitch.tv/dashducks" });
  console.log(`--------------------------------------------------------`)
  console.log(`Current Servers In:`)
  console.log(``)
  client.guilds.cache.forEach((guild) => {
    console.log(`  - ${guild.name.blue}`);
  });
  console.log(`--------------------------------------------------------`)
});

client.on(Events.InteractionCreate, async interaction => {
  if (!interaction.isChatInputCommand()) return;
    const command = interaction.client.commands.get(interaction.commandName);

    if (!command) {
        console.error(`No command matching ${interaction.commandName} was found.`);
        return;
    }

    try {
        await command.execute(interaction);
    } catch (error) {
        console.error(error);
        if (interaction.replied || interaction.deferred) {
            await interaction.followUp({ content: 'There was an error while executing this command!', ephemeral: true });
        } else {
            await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
        }
    }
});

module.expots = client;

client.login(token).then(() => {
  loadEvents(client);
  loadCommands(client);
})

const express = require('express')
const app = express();
const port = 2000;

app.get('/', (req, res) => {
  res.send('Hello World! ☀️');
})

  app.listen(port, () => {
  console.log(`- App webview active at http://localhost:${port}`)
})

Tried searching for users with similar issues but couldn't find much :( Not too familiar with coding errors so i'm open to suggestions when it comes to reading resources, please help me learn!

Let me know if anything else might be needed. Thanks in advance!


Solution

  • In line 73 of index.js, you're calling execute for commands with await command.execute(interaction);, without passing client as the second parameter. Simply do that to fix your issue.