2025, Dec 08 21:00

Remove a User’s Roles in Two Discord Servers by ID with discord.py (Guilds, Roles, Members)

Learn how to use discord.py to remove a user’s roles in two different guilds by ID: fetch guilds, resolve roles and members, revoke roles across servers.

Removing a role from a user is straightforward when everything happens inside a single server. The moment you need to revoke roles from the same user across two different servers, typical examples fall short. The task boils down to addressing the correct Guild objects by id, resolving the right Role objects, and applying the change to the user’s membership in each server explicitly.

Problem statement

You need a Discord bot built with discord.py that removes two specific roles from the same user, each role belonging to a different server. Most examples only target the current server where a command or event fires, and don’t show how to work across multiple guilds by id.

Typical one-guild-only approach (why it’s not enough)

The common pattern focuses on the current server context. That works locally but doesn’t touch roles in other servers.

@app.command()
async def drop_local(ctx, user: discord.Member, role: discord.Role):
    await user.remove_roles(role)
    await ctx.send("Role removed in this server only.")

This code removes a role in the server where the command runs. It doesn’t address any other guilds and doesn’t use ids to target them.

Core idea behind the fix

To affect multiple servers, you must explicitly fetch each target Guild using its id, then get the corresponding Role and the user’s membership in that specific guild, and only then call discord.Member.remove_roles. The sequence is: retrieve guild by id, get role by id from that guild, resolve the user as a member of that guild, and remove the role. Repeat for the second guild.

Working solution with role removal in two servers

The following example uses two guild ids and two role ids. It obtains both guilds via client.get_guild, resolves the roles with guild.get_role, finds the user in each guild through guild.get_member, and calls discord.Member.remove_roles twice. The flow is minimal and can be adapted as needed.

@app.command()
async def strip_multi(ctx, target: discord.Member):
    g_a = core.get_guild(<ID>)  # id of the first guild
    r_a = g_a.get_role(<Role ID>)  # id of the first guild's role
    g_b = core.get_guild(<ID>)  # id of the second guild
    r_b = g_b.get_role(<Role ID>)  # id of the second guild's role
    m_a = g_a.get_member(target.id)
    await m_a.remove_roles(r_a)
    m_b = g_b.get_member(target.id)
    await m_b.remove_roles(r_b)
    await ctx.send("Roles are removed from the user.")

This flow relies on the following API surfaces: discord.Client.get_guild to resolve each server by id, discord.Guild.get_role to find the correct role in that server, discord.Guild.get_member to resolve the user in that guild, and discord.Member.remove_roles to perform the revocation.

Why this matters

Discord objects are scoped. A role belongs to a specific guild, and a user’s membership and roles are also per guild. If the code only references the current context, changes won’t propagate to other servers. Explicitly targeting both guilds by id ensures you act on the correct Role and the correct Member in each place.

Takeaways

When your bot must operate across servers, don’t rely on the implicit context. Fetch the Guild you need, then the Role and the Member within that Guild, and apply the change. Keep your ids on hand, wire them in a clear sequence, and only then call the action method. The example above is intentionally lean so you can adjust it to your own command structure and project layout.