Search code examples
javascriptnode.jsdiscorddiscord.js

TypeError: Cannot read properties of undefined (reading 'guild'), Discord.JS v14, NodeJS 16


Console errors with error in title, command code below (getnews.js)


import { SlashCommandBuilder, Client, } from 'discord.js';
const client = Client
const message = client.msg

// Creates an Object in JSON with the data required by Discord's API to create a SlashCommand
const create = () => {
    const command = new SlashCommandBuilder()
        .setName('getnews')
        .setDescription('Assigns role for bot news.')

    return command.toJSON();
};

// Called by the interactionCreate event listener when the corresponding command is invoked
const invoke = (interaction) => {
    let role = message.guild.roles.cache.find(role => role.name === "Bot News");
    let member = message.member
    member.roles.add(role).catch(console.error);
};

export { create, invoke };


What i did: Tried to make it so that when you run a command it grants you a role.

Result: Bot just crashes with the error in title.

detailed error:

Successfully logged in as user#tag
file:///C:/Users/Logan/Documents/harrisbot2.0/events/commands/getnews.js:16
        let role = message.guild.roles.cache.find(role => role.name === "Bot News");
                           ^

TypeError: Cannot read properties of undefined (reading 'guild')
    at Module.invoke (file:///C:/Users/Logan/Documents/harrisbot2.0/events/commands/getnews.js:16:21)
    at Module.invoke (file:///C:/Users/Logan/Documents/harrisbot2.0/events/interactionCreate.js:8:58)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)What


Solution

  • The Client you imported from discord.js doesn't have an exported property called msg. According to you, this function will be run by the interactionCreate event listener, and so you will have an interaction. Then, the best way for you to find roles, add roles, send messages etc., would be to use the interaction itself instead of a message. Your fixed code would look like this:

    import { SlashCommandBuilder, Client } from 'discord.js';
    
    const create = () => {
        const command = new SlashCommandBuilder()
            .setName('getnews')
            .setDescription('Assigns role for bot news.')
    
        return command.toJSON();
    };
    
    const invoke = async (interaction) => {
        await interaction.guild.roles.fetch()
        let role = interaction.guild.roles.cache.find(role => role.name === "Bot News");
        let member = interaction.member
        member.roles.add(role).catch(console.error);
    };
    
    export { create, invoke };
    

    (Note: With .cache.find(), sometimes the value might not be there in the cache, which is why I added the .fetch() before.)