Discord bot channel cleanup causing dictionary iteration error

I’m working on a Discord bot in Python that creates and removes channels based on user commands. I need to build a cleanup function that checks all server channels and removes the ones that are no longer needed.

Here’s my current approach:

async def cleanupChannels():
    while True:
        await asyncio.sleep(15)
        
        pattern = re.compile(r"[0-9]*_[a-z0-9]*-[0-9]*")
        
        for currentChannel in bot.get_all_channels():
            if pattern.match(currentChannel.name):
                raidNumber = int(currentChannel.name[0])
                activeRaid = raidList[raidNumber]
                currentTime = datetime.datetime.now()
                
                if activeRaid.endTime < currentTime:
                    if activeRaid.removeRaid():
                        channelId = activeRaid.channel.id
                        await updateRaidList(activeRaid)
                        await bot.delete_channel(bot.get_channel(channelId))

Sometimes this works fine, but other times I get a RuntimeError saying ‘dictionary changed size during iteration’. I think this happens because get_all_channels() returns a dictionary and I’m modifying it while iterating. What’s the best way to handle channel deletion without this error?

classic iteration problem. copy the channels first: channels = list(bot.get_all_channels()) then loop through that. you’re iterating over a snapshot instead of the live dict that keeps changing as you delete things.

The dictionary iteration error occurs because Discord.py modifies its channel cache when you delete channels, changing the collection while looping through it. While creating a snapshot is a useful approach, consider using guild.channels for better control over specific servers. Alternatively, gather all channels for deletion first and then proceed with deletions in a separate loop. I’ve found that inserting small delays between deletions can prevent hitting Discord’s rate limits, which can complicate bulk operations.

Had this same problem building a cleanup system last year. The issue is get_all_channels() returns a view of Discord’s cache, and that cache changes when you delete channels. Don’t just copy the channels - grab the IDs first, then delete them separately. I use something like channels_to_delete = [ch.id for ch in bot.get_all_channels() if pattern.match(ch.name) and should_delete(ch)] then loop through those IDs for deletion. Way more reliable, plus you can log which channels you’re about to nuke before actually doing it. Saved me from edge cases where other processes already deleted stuff.