Race Condition when Adding Roles (Adding Roles becomes "Replace Roles" instead)
See original GitHub issueWhich package is this bug report for?
discord.js
Issue description
When adding a role, Discord.js disregards additional roles added after the current add role event is run and instead replaces them with the roles that were current at that time. Not sure how I can show code examples (because the issue involves two bots, one is DSB and the other one from Memberful, but I can show you what I see from my debugger, step by step.
To replicate this, you would need to have a Memberful Pro account (a non-paid version can be signed up to test) and that account needs to integrate with the Discord server you’re about to test on. The Gold and Platinum plans are in one plan family.
Bots Involved for Reference ONLY DSB (uses Discord.js) Memberful Bot
Roles Involved for Reference ONLY
Basic - 841111442128371712
Gold - 844316656582000680
Platinum - 844286730583801858
@ everyone - 840936982951886887
Step 1:
Start the user with a Gold role (844316656582000680
). The user should already be signed up to the Gold plan in Memberful.
Step 2:
Upgrade the user to Platinum in Memberful, where the Memberful bot removes the Gold role (844316656582000680
).
Step 3:
This is where the race condition starts. When the Gold role (844316656582000680
) is removed, the user is left with no roles. Then an event starts from DSB to add the Basic role (841111442128371712
). At this time, the cache only states that the user has the @ everyone (840936982951886887
) role.
Step 4:
Memberful proceeds to add the Platinum role (844286730583801858
) to the user.
Step 5:
DSB runs the add
method from GuildMemberRoleManager
and proceeds to replace the role added in Step 4. Notice how there isn’t a Platinum role (844286730583801858
) in the newRoles
constant?
Code sample
No response
Package version
13.6.0
Node.js version
16.13.2 (typescript 4.6.3)
Operating system
No response
Priority this issue should have
Medium (should be fixed soon)
Which partials do you have configured?
No Partials
Which gateway intents are you subscribing to?
Guilds, GuildMembers, GuildBans, GuildEmojisAndStickers, GuildInvites, GuildVoiceStates, GuildPresences, GuildMessages, GuildMessageReactions, DirectMessages
I have tested this issue on a development release
No response
Issue Analytics
- State:
- Created a year ago
- Comments:6 (2 by maintainers)
Top GitHub Comments
As long as the member isn’t removed from the cache, the cache belonging to the manager will remain updated. If I’m not wrong, members don’t get uncached normally, only if you’ve used a
CacheFactory
to override the default cacheImplementing a timeout would actually solve it. The issue comes primarly from the fact that without any timeout, both bots act on current (equal) cache, each one adding a different role. Discord.js does update cache upon receiving events, which means that if you wait “long enough” to receive an event about member having roles updated by a different bot, calling
add
after that will not produce any issues, as theadd
will work with cache that already includes the role given by the other bot.