Discord.py: Weird behaviour when moving roles.

Created on 18 Nov 2020  路  10Comments  路  Source: Rapptz/discord.py

Summary

When creating multiple ordered roles in a for loop I'm creating a role, getting a bookmark role position, and then setting the new role position to bookmark role position -1. Somehow, roles manage to be moved incorrectly, move other roles, which were pre-existing and in general not work.

Reproduction Steps

   for missing_role in missing_roles:
        role = discord.utils.get(member.guild.roles, name=f'{missing_role} {skills[missing_role.lower()]}')
        if role is not None:
            new_roles.append(role)
        else:
            role = await member.guild.create_role(name=f"{missing_role} {skills[missing_role.lower()]}", color=Colour(value=int(ROLE_COLORS[missing_role.lower()], 16)), reason='Updating skills')
            closest_position = discord.utils.get(member.guild.roles, name=f'{missing_role} Bookmark').position
            print(member.guild.roles)
            print(f'{role}         {role.position}       {closest_position-1}')
            await role.edit(position=closest_position-1)

Expected Results

Was expecting it to go from this:
image

To this:
image

Actual Results

Results are +- different each time

Went from this:
image

To this:
image

Things, like bookmarks shouldn't be moved at all.

Log from the prints:
quick_log.txt

Intents

intents = discord.Intents().default()
intents.members = True

Checklist

  • [x] I have searched the open issues for duplicates.
  • [x] I have shown the entire traceback, if possible.
  • [x] I have removed my token from display, if visible.
  • [x] I have provided the intents that my bot is using.

System Information

  • Python v3.7.4-final
  • discord.py v1.5.1-final
  • aiohttp v3.6.3
  • system info: Windows 10 10.0.18362
bug

Most helpful comment

Create all your roles then use edit_role_positions. This edits all the role positions at once and sidesteps the cache-out-of-date-discord-out-of-date issue

All 10 comments

This is likely due to Discord's role and channel position APIs being eventually consistent.

Any way around this issue?

Any way around this issue?

This is a Discord limitation.

That said, updating the position of all roles - one by one - to incremental values should get them consistent on the server, then updating the incorrectly positioned roles may solve this, and has done so for me in the past. There is no guarantee that this will not break again.

Create all your roles then use edit_role_positions. This edits all the role positions at once and sidesteps the cache-out-of-date-discord-out-of-date issue

I'll try doing that.
Quick question. Why was the code I provide moving roles that it shouldn't?

Discord doesn't provide a way to move a singular role at once- you actually edit the positions of every role. Discord.py uses it's internal cache to calculate the new role positions for everything, but when you do that in a loop, the positions get rapidly out of date and fuckery happens. Using edit_role_positions does this all at once, avoiding cache, and fuckery.

Updated some code, at least now the roles are in the correct order, but not correct positions, and the positions seem to +- shift randomly each time I run it.

Code used:

    for missing_role in missing_roles:
        role = await member.guild.create_role(name=f"{missing_role} {skills[missing_role.lower()]}", color=Colour(value=int(ROLE_COLORS[missing_role.lower()], 16)), reason='Updating skills')
        new_roles.append(role)

    for role in new_roles:
        result = re.search('^(Alchemy|Combat|Enchanting|Farming|Fishing|Foraging|Mining|Taming) ([0-9]+)', role.name)
        closest_position = discord.utils.get(member.guild.roles, name=f'{result.group(1)} Bookmark').position
        new_roles2[role] = closest_position - 1

    print(new_roles2)
    await member.guild.edit_role_positions(new_roles2)

First run:
image
Deleted the roles and tried again:
image

The position shifts each run.

Well, this sucks. Got rate-limited and have no choice but to retry experimenting in 5 hours...

EDIT: Was thinking about an upcoming event for me and said the wrong amount of time.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Nicba1010 picture Nicba1010  路  3Comments

reuscam picture reuscam  路  3Comments

Spyder-exe picture Spyder-exe  路  3Comments

MrBrahm picture MrBrahm  路  3Comments

superloach picture superloach  路  3Comments