You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord.py角色重分配报错NotFound(10011)求解决方案

问题分析与解决方案

核心错误原因

  1. 角色获取函数调用错误:你误用了discord.utils.get_role,这个函数并不存在,正确获取角色的方式是member.guild.get_role(role_id)或者discord.utils.get(member.guild.roles, id=role_id)。
  2. CSV数据格式不一致:当用户属于试用角色时,你写入CSV的是字符串格式的角色ID("934070928281841664"),其他场景则写入整数ID列表。ast.literal_eval解析后,字符串ID无法匹配整数类型的角色ID,导致找不到对应角色。
  3. CSV读取方式错误:你用csv.DictReader读取CSV,但写入时未添加表头,DictReader会把第一行数据当成表头,导致后续行的索引匹配完全错误,应该用csv.reader读取无表头的CSV文件。

修正后的代码

import discord
import asyncio
import csv
import ast

intents = discord.Intents().all()
client = discord.Client(intents=intents)

async def background_task(member, role):
    await asyncio.sleep(30)  # 测试用30秒,正式环境改成86400*14对应14天
    new_role = member.guild.get_role(934070928281841664)  # 用ID获取角色更可靠
    if new_role:
        await member.remove_roles(role)
        await member.add_roles(new_role)
        print(f'User {member} has been taken off trial')
    else:
        print("Trader角色不存在,无法完成切换")

@client.event
async def on_member_join(member):
    print(f"User joined: {member.id}")
    has_record = False
    # 用csv.reader读取无表头的CSV
    with open("roles.csv", "r", encoding="utf-8") as csv_file:
        reader = csv.reader(csv_file)
        print("CSV was opened")
        
        for row in reader:
            if not row:  # 跳过空行避免报错
                continue
            str_member = str(member.id)
            if row[0] == str_member:
                has_record = True
                print(row[0], str_member)
                print(f"row[1]: {row[1]}")
                try:
                    role_ids = ast.literal_eval(row[1])
                    # 处理单个ID的情况,统一转为列表格式
                    if not isinstance(role_ids, (list, tuple)):
                        role_ids = [role_ids]
                    # 强制转换为整数ID,避免字符串匹配失败
                    roles = []
                    for rid in role_ids:
                        rid = int(rid)
                        role = member.guild.get_role(rid)
                        if role:
                            roles.append(role)
                    print(f"Roles: {roles}")
                    
                    if roles:
                        await member.add_roles(*roles)
                        print(f"User found, roles restored")
                    else:
                        print("No valid roles found for this user")
                except Exception as e:
                    print(f"解析角色数据出错: {e}")
                break  # 找到用户后直接跳出循环,减少不必要的遍历
    
    # 只有无记录时才分配试用角色
    if not has_record:
        role = discord.utils.get(member.guild.roles, name="Insider Trial")
        if role:
            await member.add_roles(role)
            asyncio.create_task(background_task(member, role))
            print("New user assigned trial role")
        else:
            print("Insider Trial角色不存在,无法分配")

@client.event
async def on_member_remove(member):
    trial_removal = "Insider Trial"
    roles = [role.name for role in member.roles]
    print(f"{member.name} had the following roles: {', '.join(roles)}")

    with open("roles.csv", "a", newline="", encoding="utf-8") as csv_file:
        writer = csv.writer(csv_file)
        if trial_removal in roles:
            # 统一用整数ID列表格式写入,避免类型混乱
            writer.writerow([member.id, [934070928281841664]])
            print("This user was on trial")
        else:
            # 过滤掉默认的@everyone角色(ID等于服务器ID),避免无效数据
            role_ids = [role.id for role in member.roles if role.id != member.guild.id]
            writer.writerow([member.id, role_ids])
            print("User's roles were recorded!")

client.run('YOUR_BOT_KEY_HERE')

额外优化说明

  • 增加了异常处理,避免解析CSV数据时程序崩溃
  • 统一CSV写入格式为整数ID列表,彻底解决类型不匹配问题
  • 使用guild.get_role获取角色,比discord.utils.get效率更高
  • 找到用户记录后立即跳出循环,减少不必要的遍历开销
  • 过滤默认的@everyone角色,避免存储无效数据

内容的提问来源于stack exchange,提问作者Slade

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 09:55:13