Skip to content

UnhandledPromiseRejectionWarning: TypeError: Cannot read property ‘voice’ of undefined. In play.js when trying to run a command

I get the error UnhandledPromiseRejectionWarning: TypeError: Cannot read property ‘voice’ of undefined in my code. Is it a problem with dependencies or is it an error in the code. This is my code.

const Discord = require('discord.js');

module.exports = {
    name: 'play',
    aliases: ['p'],
    description: 'plays a song/nasheed',

    async execute (client, message, args) {
        if(!message.member.voice.channel) return message.reply('Pleases be in a vc to use this command.');

        const music = args.join(" "); //&play song name
        if(!music) return message.reply("Invalid song/nasheed name.");

        await client.distube.play(message, music);
    }

}

This is my bot.js code

const fs = require('fs');
const Discord = require("discord.js");
const { prefix, token } = require('./config.json');



const client = new Discord.Client();
client.commands = new Discord.Collection();
client.cooldowns = new Discord.Collection();


const commandFolders = fs.readdirSync('./src/commands');

for (const folder of commandFolders) {
    const commandFiles = fs.readdirSync(`./src/commands/${folder}`).filter(file => file.endsWith('.js'));
    for (const file of commandFiles) {
        const command = require(`./src/commands/${folder}/${file}`);
        client.commands.set(command.name, command);
    }
    
}



client.once('ready', () => {
    console.log('bot is online');


client.user.setPresence({
    status: 'available',
    activity: {
        name: 'Answering &help',
        type: 'WATCHING',
        url: 'https://www.youtube.com/channel/UC1RUkzjpWtp4w3OoMKh7pGg'
    }
});
});
 
client.on('message', message => {
        if (!message.content.startsWith(prefix) || message.author.bot) return;
    
        const args = message.content.slice(prefix.length).trim().split(/ +/);
        const commandName = args.shift().toLowerCase();
    
        const command = client.commands.get(commandName)
            || client.commands.find(cmd => cmd.aliases && cmd.aliases.includes(commandName));
    
        if (!command) return;
    
        if (command.guildOnly && message.channel.type === 'dm') {
            return message.reply('I can't execute that command inside DMs!');
        }
    
        if (command.permissions) {
            const authorPerms = message.channel.permissionsFor(message.author);
            if (!authorPerms || !authorPerms.has(command.permissions)) {
                return message.reply('You can not do this!');
            }
        }
        try {
            command.execute(message, args);
        } catch (error) {
            console.error(error);
            message.reply('there was an error trying to execute that command!');
        }
    });

const distube = require('distube');
client.distube = new distube(client, { searchSongs: false, emitNewSongOnly: true });
client.distube
    .on('playSong', (message, queue, song) => message.channel.send(
        `Playing `${song.name}` - `${song.formattedDuration}`nRequested by: ${song.user}n${status(queue)}`,
    ))
    .on('addSong', (message, queue, song) => message.channel.send(
        `Added ${song.name} - `${song.formattedDuration}` to the queue by ${song.user}`,
    ))
    .on('error', (message, e) => {
        //console.error(e)
        message.channel.send(`An error encountered: ${e}`)
    })

client.login(token);

This is a music command which i am trying to make an requires you to be in a voice channel in discord to work.

Answer

The issue you have is a misplacement of the variables you are passing to execute the command. On your /play command file, you must change this line:

async execute (client, message, args)

To

async execute (client, message, args, Discord)

And you can get rid of the

const Discord = require('discord.js');

Since you will now be passing the Discord variable from your command fetcher. But to actually pass in the variable, you gotta go to your bot.js file and change the following lines:

        try {
            command.execute(message, args);
        } catch (error) {
            console.error(error);
            message.reply('there was an error trying to execute that command!');
        }

To this:

        try {
            command.execute(client, message, args, Discord);
        } catch (error) {
            console.error(error);
            message.reply('there was an error trying to execute that command!');
        }

The variables you will be passing are (client, message, args, Discord), meaning you just need to add them for every single command you will create, otherwise the command won’t work.

The reason why your current command was not working was that you were not calling the client variable after executing the command, meaning the variable message was on the spot of your client variable, having said this, you always got to keep in mind to place these variables (client, message, args, Discord) exactly on the same order as they are in your bot.js file, otherwise, the command will always throw an issue, since they must all be stated, and in the same order.

I hope this helped! Best of luck with your project.