{"record":{"id":"d1efca532ca1ab81","repo":"flipped-aurora/gin-vue-admin","slug":"w-d1efca","errorCode":null,"errorMessage":"获取角色列表失败: %w","messagePattern":"获取角色列表失败: %w","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mcp/org_common.go","lineNumber":183,"sourceCode":"\n// findAuthorityInTree 在角色树中按 authorityId 查找角色\nfunc findAuthorityInTree(list []system.SysAuthority, id uint) *system.SysAuthority {\n\tfor i := range list {\n\t\tif list[i].AuthorityId == id {\n\t\t\treturn &list[i]\n\t\t}\n\t\tif found := findAuthorityInTree(list[i].Children, id); found != nil {\n\t\t\treturn found\n\t\t}\n\t}\n\treturn nil\n}\n\n// fetchAuthority 拉取角色树并定位目标角色(getAuthorityList 返回调用者可见的角色树)\nfunc fetchAuthority(ctx context.Context, authorityID uint) (*system.SysAuthority, error) {\n\tresp, err := postUpstream[[]system.SysAuthority](ctx, \"/authority/getAuthorityList\", map[string]any{})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"获取角色列表失败: %w\", err)\n\t}\n\tauthority := findAuthorityInTree(resp.Data, authorityID)\n\tif authority == nil {\n\t\treturn nil, fmt.Errorf(\"角色 %d 不存在或当前token无权查看\", authorityID)\n\t}\n\treturn authority, nil\n}\n\n// scanUsersByIDs 按ID集合补全用户信息:上游 getUserList 不支持按ID过滤,翻页扫描至集齐或达页数上限,\n// 返回 命中映射 与 未解析ID 列表(行级可见范围由主服务侧 datascope 引擎决定)\nfunc scanUsersByIDs(ctx context.Context, ids []uint) (map[uint]system.SysUser, []uint, error) {\n\twant := make(map[uint]struct{}, len(ids))\n\tfor _, id := range ids {\n\t\twant[id] = struct{}{}\n\t}\n\tfound := make(map[uint]system.SysUser, len(ids))\n\n\tfor page := 1; page <= orgUserScanMaxPages && len(found) < len(want); page++ {","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/mcp/org_common.go#L165-L201","documentation":"fetchAuthority fetches the role tree via POST /authority/getAuthorityList; if that upstream call itself fails, the error is wrapped as 获取角色列表失败. Note this is distinct from the role simply not being found (error 393).","triggerScenarios":"Any MCP org tool resolving a role/authority (fetchAuthority via Handle) while POST /authority/getAuthorityList fails at the transport layer or returns a non-success response code: network failure, invalid token, upstream panic/5xx.","commonSituations":"MCP server cannot reach the main service; token expired; upstream service returning 500; response body not matching the expected envelope so postUpstream decodes it as an error.","solutions":["Verify the upstream service is reachable and /authority/getAuthorityList returns 200 with code 0","Refresh/re-issue the upstream token used by the MCP server","Inspect the wrapped cause in logs to identify transport vs upstream-code failure","Check for version drift between the MCP tool and the main service API envelope"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// pre-check role tree availability\nconst res = await fetch(baseUrl + '/authority/getAuthorityList', { method: 'POST' })\nif (!res.ok) throw new Error('authority list unavailable')","typeGuard":null,"tryCatchPattern":"try {\n  await callMcpTool(tool, args)\n} catch (e) {\n  if (String(e.message).includes('获取角色列表失败')) {\n    // check connectivity/token, inspect wrapped cause, retry with backoff\n  }\n}","preventionTips":["Keep the MCP upstream token valid and scoped to see needed roles","Alert on /authority/getAuthorityList failures","Differentiate this error from '角色 %d 不存在...' (393) when diagnosing"],"tags":["network","upstream-api","mcp","roles"],"backgroundTag":"upstream-request-failed","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}