{"record":{"id":"dab5bced6000751a","repo":"flipped-aurora/gin-vue-admin","slug":"api-w-dab5bc","errorCode":null,"errorMessage":"分配API权限失败: %w","messagePattern":"分配API权限失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mcp/role_api_assigner.go","lineNumber":89,"sourceCode":"\t\tmethod = value\n\t}\n\n\tpath, method = normalizePolicy(path, method)\n\tcurrentResp, err := postUpstream[map[string][]systemReq.CasbinInfo](ctx, \"/casbin/getPolicyPathByAuthorityId\", map[string]any{\n\t\t\"authorityId\": authorityID,\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"获取角色当前API权限失败: %w\", err)\n\t}\n\n\tcurrent := currentResp.Data[\"paths\"]\n\tupdated, added := appendPolicyIfMissing(current, path, method)\n\tif added {\n\t\tif _, err = postUpstream[map[string]any](ctx, \"/casbin/updateCasbin\", map[string]any{\n\t\t\t\"authorityId\": authorityID,\n\t\t\t\"casbinInfos\": updated,\n\t\t}); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"分配API权限失败: %w\", err)\n\t\t}\n\t}\n\n\tmsg := \"权限已存在，无需重复分配\"\n\tif added {\n\t\tmsg = fmt.Sprintf(\"成功为角色 %d 分配权限 %s %s\", authorityID, method, path)\n\t}\n\n\treturn textResultWithJSON(\"角色API权限分配结果：\", roleAPIAssignResponse{\n\t\tSuccess:       true,\n\t\tMessage:       msg,\n\t\tAuthorityID:   authorityID,\n\t\tPath:          path,\n\t\tMethod:        method,\n\t\tAdded:         added,\n\t\tAlreadyExists: !added,\n\t\tTotalPolicies: len(updated),\n\t})","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/mcp/role_api_assigner.go#L71-L107","documentation":"Wrap of an upstream error from POST /casbin/updateCasbin when writing the updated policy list for a role. The read succeeded and appendPolicyIfMissing detected a new path/method pair, but the write failed.","triggerScenarios":"Handle posts the full updated casbinInfos to /casbin/updateCasbin and the upstream returns an error — network, auth, invalid authorityId, or a policy entry the backend rejects (e.g. API path not registered).","commonSituations":"Target path/method not present in the backend API registry; role deleted concurrently; MCP token lacking casbin write permission; transient backend outage.","solutions":["Read the wrapped cause for the exact upstream rejection reason","Verify the API path+method exists in the backend API list before assigning","Confirm the authorityId still exists and the token has write access","Retry once backend health is confirmed"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"apis, err := client.ListAPIs(ctx)\nif err != nil { return err }\nknown := map[string]bool{}\nfor _, a := range apis { known[a.Method+\" \"+a.Path] = true }\nif !known[method+\" \"+path] {\n    return fmt.Errorf(\"API %s %s is not registered\", method, path)\n}","typeGuard":null,"tryCatchPattern":"_, err := assigner.Handle(ctx, args)\nif err != nil {\n    if strings.Contains(err.Error(), \"分配API权限失败\") {\n        // write-phase failure: the read succeeded, so the role exists;\n        // inspect the wrapped cause and retry idempotently if network/5xx\n    }\n    return err\n}","preventionTips":["Verify the path+method pair exists in the backend API registry first","Keep write tokens scoped and unexpired","Treat assignment as idempotent and safe to retry"],"tags":["casbin","upstream-api","permissions"],"backgroundTag":"upstream-api-call-failed","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}