flipped-aurora/gin-vue-admin · error
批量分配API权限失败: %w
Error message
批量分配API权限失败: %w
What it means
This error wraps any failure returned by the upstream `/casbin/updateCasbin` HTTP endpoint when the role-API batch assigner flushes the accumulated new Casbin policies. The `%w` keeps the underlying transport or server error intact. It means the local batch computation succeeded but persisting the policy changes to the server failed.
Source
Thrown at server/mcp/role_api_batch_assigner.go:115
Path: path,
Method: method,
Added: added,
AlreadyExists: !added,
})
if added {
result.AddedCount++
anyAdded = true
} else {
result.SkippedCount++
}
}
if anyAdded {
if _, err := postUpstream[map[string]any](ctx, "/casbin/updateCasbin", map[string]any{
"authorityId": authorityID,
"casbinInfos": updated,
}); err != nil {
return nil, fmt.Errorf("批量分配API权限失败: %w", err)
}
}
result.TotalPolicies = len(updated)
result.Message = fmt.Sprintf("角色 %d 批量授权完成:新增 %d 条,已存在跳过 %d 条,当前共 %d 条策略",
authorityID, result.AddedCount, result.SkippedCount, result.TotalPolicies)
return textResultWithJSON("角色API权限批量分配结果:", result)
}
// parseAPIItems 解析 apis 参数,支持 JSON 数组[{path,method}]与"METHOD /path"逗号分隔字符串双格式,
// 批内按 归一化path+method 去重
func parseAPIItems(v any) ([]systemReq.CasbinInfo, error) {
if v == nil {
return nil, nil
}
var items []systemReq.CasbinInfo
appendItem := func(path, method string) {View on GitHub (pinned to 3136500ef3)
Solutions
- Inspect the wrapped cause (`%w`) to see if it is a network error or an upstream API error response
- Verify the MCP upstream base URL and that the gva server is running and reachable
- Re-authenticate: an expired JWT on /casbin/updateCasbin is a common cause; refresh the token
- Confirm authorityId exists via the role query tool before assigning APIs
- Retry the operation; assignment is idempotent for already-existing policies (they are skipped)
Example fix
// before
_, err := postUpstream[map[string]any](ctx, "/casbin/updateCasbin", payload)
// after
if _, err := postUpstream[map[string]any](ctx, "/casbin/updateCasbin", payload); err != nil {
log.Printf("casbin update failed (authorityId=%d, policies=%d): %v", authorityID, len(updated), err)
return nil, fmt.Errorf("批量分配API权限失败: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// verify role exists before batch assignment
role, err := fetchAuthority(ctx, authorityID)
if err != nil {
return fmt.Errorf("role %d not found: %w", authorityID, err)
} Type guard
func isValidAuthority(id uint, known map[uint]struct{}) bool {
_, ok := known[id]
return ok
} Try / catch
result, err := assigner.Handle(ctx, args)
if err != nil {
var upstreamErr *UpstreamError
if errors.As(err, &upstreamErr) {
// retry once or refresh token before surfacing
}
return err
} Prevention
- Confirm the role exists before assignment
- Keep the MCP-to-server JWT fresh
- Check server health before large batch operations
- Rely on idempotency: re-running skips existing policies
When it happens
Trigger: Calling the batch API-permission assignment MCP tool where at least one policy was newly added and the POST to /casbin/updateCasbin returns non-nil (network failure, upstream 4xx/5xx, invalid authorityId, malformed casbinInfos).
Common situations: Upstream gva server down or restarted mid-session; JWT token expired so upstream returns 401; authorityId references a role deleted on the server; proxy/firewall blocking the internal API route.
Related errors
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/08ee1f0f719b966d.
Report an issue: GitHub.