快速结论:该报错通常出现在自托管 Dify 1.17.0 中,通过 Dataset Service API(如 GET /v1/datasets)调用知识库时,Member 账号创建的 only_me 知识库不会出现在列表里,但直接 GET /v1/datasets/{id} 却返回 200。优先排查 Service API 令牌校验时是否固定以工作区 Owner 身份执行,以及列表端点是否沿用了按用户可见性过滤的旧逻辑。
适用环境:Issue 已确认:Dify 1.17.0(langgenius/dify-api:1.17.0),Self Hosted(Docker Compose)。其他 Python、CUDA、显卡或依赖版本信息 Issue 未提供。
最快修复方案:暂无确认的一步修复方案。Issue 讨论中仅把“在 Service API 的列表端点跳过按用户的可见性过滤,使其与单资源 GET 行为一致”作为可优先尝试的最小改动方向,尚未验证或合入。
注意事项:上述改动属于代码层修复,涉及 api/controllers/service_api/dataset/dataset.py 与 api/services/dataset_service.py 的过滤逻辑;讨论还提到服务层 user=None 的回退分支当前只返回 ALL_TEAM 数据集,若要改为返回 tenant 内全部数据集需要额外调整。升级前请评估 Service API 令牌的权限语义变化,不要据此认为问题已官方修复。
问题场景
用户在自托管 Dify 1.17.0 的工作区中同时存在 Owner 与 Member(editor)账号,并用 Knowledge Base Service API key 调用 GET /v1/datasets 拉取知识库列表。结果列表恰好等于 Owner 的个人视图:Owner 自己创建的 3 个 only_me 数据集和共享给 Owner 的 partial_members 数据集可见,而 Member 创建的 5 个 only_me 数据集全部缺失,即便使用由该 Member 创建的 API key 也一样。随后用同一令牌直接请求 Member 私有数据集的 GET /v1/datasets/{id},却返回 HTTP 200 和完整详情,形成列表与直读不一致。
报错原文
Bug: Dataset Service API ignores per-user knowledge base permissions — every token is authorized as the workspace Owner (list vs direct GET inconsistent)
GET /v1/datasets -> Owner's only_me datasets returned, Member's only_me datasets omitted
GET /v1/datasets/{member_only_me_dataset_id} -> HTTP 200 with full dataset detail
原因分析
根据 Issue 正文与维护者回复的代码定位,原因大致如下:
validate_dataset_token(api/controllers/service_api/wraps.py,约 342–361 行)会通过TenantAccountJoin.role IN ('owner')查出工作区 Owner 账号,并调用_update_request_context_with_user(account)将其设为当前用户;代码中带TODO: only owner information is required注释,说明这是有意的设计选择,但带来了非预期的副作用。GET /v1/datasets把被冒充的 Owner 作为current_user传入DatasetService.get_datasets(api/services/dataset_service.py),随后套用旧的按用户过滤条件ONLY_ME AND maintainer == user.id OR ALL_TEAM OR PARTIAL_TEAM AND id IN permitted_ids,因此结果反映的是 Owner 个人视图,而非工作区级 API 访问。- 单数据集路径
DatasetApiResource走check_dataset_permission(dataset, current_user, session),当user.current_role == TenantAccountRole.OWNER时跳过ONLY_ME检查,所以被冒充的 Owner 能读取 tenant 内任意数据集,包括 Member 私有数据集,这解释了列表与直读不一致。 - 由于
api_tokens没有创建者列,密钥是工作区级的,不同账号创建的令牌返回完全相同的结果。
可能原因补充:讨论中提到该问题属于更广泛的资源边界一致性工作(#37983),但其子任务 #37985 只覆盖了元数据/文档所有权,未覆盖数据集列表可见性。
环境排查
- 确认 Dify 版本是否为 1.17.0(
langgenius/dify-api:1.17.0),其他版本行为可能不同。 - 确认部署方式为 Self Hosted(Docker Compose)。
- 确认调用使用的是 Knowledge Base Service API key,而非 Web 前端会话。
- 核对测试账号的角色:是否存在 Owner 与 Member(editor)两类账号,并记录各自创建的
only_me/partial_members数据集数量。 - 对照
api/controllers/service_api/wraps.py中validate_dataset_token的实际实现,确认是否仍按 Owner 身份注入当前用户。 - Issue 未提供 Python、CUDA、PyTorch、显卡或节点依赖信息,这些不作为本问题的排查项。
解决步骤
- 先复现并记录基线:用 Owner 与 Member 各创建一个 Service API key,分别调用
GET /v1/datasets,确认两个令牌返回结果是否完全一致,以及 Member 的only_me数据集是否缺失。 - 用同一令牌对缺失的数据集调用
GET /v1/datasets/{id},确认是否返回 HTTP 200。若列表缺失但直读 200,即符合本 Issue 的典型症状。 - 在代码中定位
validate_dataset_token,确认当前用户是否被固定设置为工作区 Owner,并记录其与列表继续往下走的调用链路。 - 检查
DatasetService.get_datasets中的可见性过滤分支,确认当传入用户为 Owner 时会返回哪些数据集。 - 可优先尝试的修复方向:在
DatasetListApi.get中为 Service API 上下文绕过按用户的可见性过滤,使其与单资源 GET 的“仅校验 tenant 归属与enable_api”行为保持一致。 - 若采用上述方向,同时检查服务层
user=None的回退分支;讨论指出该分支当前只限制返回ALL_TEAM数据集,需要调整为返回 tenant 内全部数据集才能达到一致效果。 - 在改动生效后重新用两个令牌调用列表与直读端点,对比结果。
验证方法
构造与 Issue 相同的场景:Owner 3 个 only_me、Member 5 个 only_me 加 1 个共享给 Owner 的 partial_members。修复后,GET /v1/datasets 与 GET /v1/datasets/{id} 对同一数据集的可见性应一致,且 Member 的 only_me 数据集不再从列表中静默消失;由不同账号创建的 API key 结果一致性应按最终确定的权限语义核对。若未做代码修复,该问题在 1.17.0 上仍会复现,不能以单次调用成功作为解决依据。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![[Bug][HiSparse] GLM-5.3 TP8 B200: unspecified launch failure with MNNVL all-reduce (#61989) once KV spills to host](https://www.chat-gpts.plus/wp-content/uploads/2026/11/64327-1c435bd8-768x403.jpg)
![[Bug]: No sm_121 (Blackwell) support on aarch64 — NVIDIA DGX Spark / Acer GN100](https://www.chat-gpts.plus/wp-content/uploads/2026/11/36821-3a0f2ac2-768x403.jpg)
