Lost thread update when calling <ThreadChannel>.edit() #10658
Description
Which package is this bug report for?
discord.js
Issue description
When someone create a post on a server and put a very bad title like question
, our bot sends a button to edit the title post. When the user clicks on the button a modal is shown and the user has to enter the new title. When he submit the modal form I retrieve the input value and call thread.edit({ name: newNameFromInput })
However, in some cases, the threadUpdate
event received has the same object in the argument "old" and "new" and doesn't show that the new name is different from the old one as expected.
After digging in the code I saw that in the method we are calling this.client.actions.ChannelUpdate.handle(newData);
which update the data in the cache. Therefore, if this line executes before the event is received from the gateway the emitted event on the client will not expose the old name
Code sample
import { Client, Events, GatewayIntentBits, Partials } from 'discord.js';
import { token, thread } from './config.json';
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMembers
],
partials: [Partials.GuildMember, Partials.ThreadMember, Partials.Channel]
});
client.once(Events.ClientReady, readyClient => {
console.log(`Ready! Logged in as ${readyClient.user.tag}`);
});
client.on(Events.ThreadUpdate,(old, new) => {
console.log("Thread update event received", old, new);
});
await client.login(token);
// As this bug is random and depends on when each network event occurs (gateway + API call)
// You have to execute the below code multiple times
const thread = await client.channels.fetch(thread);
await thread.edit({ name: "aaaa" + Math.round(Math.random() * 100) })
// To reproduce this bug easily you can modify the file "discord.js/src/client/websocket/handlers/THREAD_UPDATE.js" by putting this code
'use strict';
const Events = require('../../../util/Events');
module.exports = (client, packet) => {
// Delay code execution to force order of code execution
setTimeout(() => {
const { old, updated } = client.actions.ChannelUpdate.handle(packet.d);
if (old && updated) {
/**
* Emitted whenever a thread is updated - e.g. name change, archive state change, locked state change.
* @event Client#threadUpdate
* @param {ThreadChannel} oldThread The thread before the update
* @param {ThreadChannel} newThread The thread after the update
*/
client.emit(Events.ThreadUpdate, old, updated);
}
}, 1_000);
};
Versions
- discord.js : 14.16.2
- Node : 20.16.0
- Typescript : 5.7.2
Issue priority
Medium (should be fixed soon)
Which partials do you have configured?
Channel, GuildMember, Message, Reaction, ThreadMember
Which gateway intents are you subscribing to?
Guilds, GuildMembers, GuildModeration, GuildEmojisAndStickers, GuildInvites, GuildVoiceStates, GuildPresences, GuildMessages, GuildMessageReactions, DirectMessages, MessageContent, AutoModerationExecution
I have tested this issue on a development release
No response