flipped-aurora/gin-vue-admin · error

获取角色当前菜单授权失败: %w

Error message

获取角色当前菜单授权失败: %w

What it means

This error wraps a failure when the role-menu assignment tool calls the upstream admin API POST /menu/getMenuAuthority to read a role's current menu authorization before modifying it. The pre-read exists to prevent accidentally overwriting/losing existing permissions when writing back a merged menu set. Any network, auth, or upstream 5xx failure surfaces here wrapped with %w.

Source

Thrown at server/mcp/role_menu_assigner.go:92

	allResp, err := postUpstream[[]system.SysBaseMenu](ctx, "/menu/getMenuList", map[string]any{})
	if err != nil {
		return nil, fmt.Errorf("获取菜单列表失败: %w", err)
	}
	menuIndex := make(map[uint]system.SysBaseMenu)
	flattenBaseMenus(allResp.Data, menuIndex)

	for _, id := range menuIDs {
		if _, ok := menuIndex[id]; !ok {
			return nil, fmt.Errorf("菜单 %d 不存在,可先用 list_all_menus 查询全部菜单", id)
		}
	}

	// 角色当前授权(先读,防覆盖丢权)
	currentResp, err := postUpstream[map[string][]system.SysMenu](ctx, "/menu/getMenuAuthority", map[string]any{
		"authorityId": authorityID,
	})
	if err != nil {
		return nil, fmt.Errorf("获取角色当前菜单授权失败: %w", err)
	}
	currentIDs := make([]uint, 0)
	for _, menu := range currentResp.Data["menus"] {
		id := menu.MenuId
		if id == 0 {
			id = menu.ID
		}
		if id != 0 && !containsUint(currentIDs, id) {
			currentIDs = append(currentIDs, id)
		}
	}

	// 请求集 = 传入菜单 ∪ 各自的完整父链
	requested := make([]uint, 0, len(menuIDs))
	parentAdded := make([]uint, 0)
	for _, id := range menuIDs {
		requested = append(requested, id)
		parentID := menuIndex[id].ParentId

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Verify the upstream gin-vue-admin server is running and reachable at the configured base URL (curl the endpoint).
  2. Check/refresh the JWT token used by the MCP HTTP client (server/mcp/http_client.go) in its config.
  3. Confirm the upstream route /menu/getMenuAuthority exists and the caller role has Casbin permission for it.
  4. Inspect the wrapped cause (%w) in the error chain for the concrete failure (timeout, 401, 500, decode error).
  5. Retry once transient failures (network blips) resolve after the backend is healthy.

Example fix

// before
resp, err := postUpstream[map[string][]system.SysMenu](ctx, "/menu/getMenuAuthority", body)
// after
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
resp, err := postUpstream[map[string][]system.SysMenu](ctx, "/menu/getMenuAuthority", body)
if err != nil {
    log.Printf("getMenuAuthority failed: %v", err) // inspect wrapped cause
    return nil, err
}
Defensive patterns

Strategy: retry

Validate before calling

// pre-check upstream reachability before invoking the assigner
resp, err := http.Get(baseURL + "/health")
if err != nil || resp.StatusCode != 200 {
    return fmt.Errorf("upstream admin server unreachable, aborting menu assignment")
}

Try / catch

result, err := assigner.Handle(ctx, args)
if err != nil {
    var netErr net.Error
    if errors.As(err, &netErr) && netErr.Timeout() {
        // transient: retry with backoff
    } else if strings.Contains(err.Error(), "401") {
        // refresh JWT then retry once
    }
    return err
}

Prevention

When it happens

Trigger: Calling the role-menu-assigner MCP Handle() with an authorityId when the HTTP POST to /menu/getMenuAuthority fails: upstream server unreachable, JWT/token invalid, upstream returns non-2xx, request context canceled, or response body cannot be decoded into {menus: []SysMenu}.

Common situations: Running the MCP tool while the gin-vue-admin backend is down or restarting; expired JWT in the MCP HTTP client config; wrong upstream base URL/port; authorityId referencing a role that makes upstream return an error; firewall/proxy blocking the internal call.

Related errors


AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31). Data as JSON: /api/errors/487c4ba99ad621ba. Report an issue: GitHub.