Bot gives the role, and then removes it (the same role).

My code:
const Discord = require("discord.js");
const bot = new Discord.Client();
bot.on('ready', () => {
const guild = bot.guilds.get('249828546153938955');
const member = guild.member(bot.users.get('146770757463179264'));
if(member) {
member.removeRoles('363796105357557761');
member.addRole('363796178304761866');
}
});
P.S. On your Discord server did not help me with this issue, so I suspect that is a bug.
Can you please fill out the issue template?
Especially this part:

Sorry, added.
Your issue here is a mixture of a race condition and the how the lib handles removing or adding of multiple roles.
That being: Modifying the cached roles of the member and them patching all of them to the api (Equal to GuildMember#setRoles). (lib handling part)
This removes your newly added role, if the role gets added before patching the others. (race condition part)
As a solution I propose that you use GuildMember#setRoles because you want to add and remove roles at the same time.
Easiest way would probably to make a set of the current role id's and then remove and add as you wish. Before passing it to setRoles simply spread it.
Small example:
const roles = new Set(member.roles.keyArray());
roles.add('someRoleId');
roles.delete('someOtherRoleId');
member.setRoles([...roles]);
And as a side note, which is not really relevant to your current issue, but could be your next:
GuildMember#removeRoles takes an array or collection of role ids or role objects.
Passing a single string will just be ignored duo the way the method iterates the string.
If that is the case the documentation of GuildMember#addRoles and GuildMember#removeRoles can be improved to reflect this behaviour and it should recommend using setRoles instead.
Any asynchronous operations are supposed to be awaited; if await was used in the example code, it would work without issue.
However, this race issue could become more prevalent regardless of which method is being used. Any attempts to set roles in parallel (which could occur; imagine two commands or events dealing with roles being processed in parallel) will cause this issue.
Most helpful comment
Your issue here is a mixture of a race condition and the how the lib handles removing or adding of multiple roles.
That being: Modifying the cached roles of the member and them patching all of them to the api (Equal to
GuildMember#setRoles). (lib handling part)This removes your newly added role, if the role gets added before patching the others. (race condition part)
As a solution I propose that you use
GuildMember#setRolesbecause you want to add and remove roles at the same time.Easiest way would probably to make a set of the current role id's and then remove and add as you wish. Before passing it to setRoles simply spread it.
Small example:
And as a side note, which is not really relevant to your current issue, but could be your next:
GuildMember#removeRolestakes an array or collection of role ids or role objects.Passing a single string will just be ignored duo the way the method iterates the string.