Discord.js 14 – Cant send an image to a specific channel when a member joins

I was trying to send an image when a member joins to my server with @napi-rs/canvas in discord.js 14.

When the bot tries to send the message this error appears.

I was trying to make it with discordjs.guide

Cannot read properties of undefined (reading 'cache')

This is the code of my event:

const { Events, AttachmentBuilder} = require('discord.js');
const Canvas = require('@napi-rs/canvas');

module.exports = {
    name: Events.GuildMemberAdd,
    async execute(client) {
        const canvas = Canvas.createCanvas(1024, 500);
        const context = canvas.getContext('2d');

        const background = await Canvas.loadImage('./resources/canvas/images/welcome.png');

        context.drawImage(background, 0, 0, canvas.width, canvas.height);
        const attachment = new AttachmentBuilder(await canvas.encode('png'), { name: 'profile-image.png' });

console.log ('sending message')
        const channel = client.channels.cache.get('1099656104100769924');
        channel.send(({ files: [attachment] }));

And this is my index.js file

const { Client, Collection, Events, GatewayIntentBits } = require('discord.js');
const fs = require('node:fs');
const path = require('node:path');

const { token, prefix } = require('./config.json');

const { channel } = require('node:diagnostics_channel');

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

client.commands = new Collection();

const foldersPath = path.join(__dirname, 'commands');
const commandFolders = fs.readdirSync(foldersPath).filter(file => file.endsWith('.js'));

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 on ${filePath} dont have  "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));


I tried many solutions and nothing worked I am using the latest version of discord.js v14.

>Solution :

The GuildMemberAdd event takes a single parameter, the member that has joined a guild. That means client in async execute(client) is not a client, but a GuildMember.

You can change it to:

async execute(member) {
  // ...

As GuildMembers have a client property, you can simply use:

const channel = member.client.channels.cache.get('1099656104100769924');

Leave a Reply