flipped-aurora/gin-vue-admin · error
单次授权菜单数量不能超过 %d 个
Error message
单次授权菜单数量不能超过 %d 个
What it means
The role-menu assigner caps a single authorization call at `orgBatchLimit` menu IDs to avoid oversized payloads and long-running casbin writes. Exceeding the cap aborts before any upstream call. The message interpolates the configured maximum.
Source
Thrown at server/mcp/role_menu_assigner.go:70
)
}
func (r *RoleMenuAssigner) Handle(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
args := request.GetArguments()
authorityID, err := parseAuthorityID(args["authorityId"])
if err != nil {
return nil, err
}
menuIDs, err := parseUintList(args["menuIds"], "menuIds")
if err != nil {
return nil, err
}
if err := requireNonEmptyList(menuIDs, "menuIds"); err != nil {
return nil, err
}
if len(menuIDs) > orgBatchLimit {
return nil, fmt.Errorf("单次授权菜单数量不能超过 %d 个", orgBatchLimit)
}
// 全量基础菜单:存在性校验、父链补齐、写回时的完整菜单对象都从这里取
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{View on GitHub (pinned to 3136500ef3)
Solutions
- Split menuIds into batches no larger than orgBatchLimit and call the tool once per batch
- Pre-filter menuIds to only the menus actually needed (sub-menus often come along with parents automatically — the tool补齐父链)
- If bulk setup is required, script multiple sequential calls and verify with a role-menu query tool
Example fix
// before
assignMenus(authorityID, allMenuIDs) // 200 ids > limit
// after
for batch := range chunk(allMenuIDs, orgBatchLimit) {
assignMenus(authorityID, batch)
} Defensive patterns
Strategy: validation
Validate before calling
if len(menuIDs) > orgBatchLimit {
return fmt.Errorf("chunk menuIds: %d exceeds limit %d", len(menuIDs), orgBatchLimit)
}
for batch := range chunk(menuIDs, orgBatchLimit) {
if err := assignMenus(ctx, authorityID, batch); err != nil {
return err
}
} Prevention
- Chunk any menuIds list before calling
- Only include menus the role actually needs
- Script multi-batch assignment for bulk provisioning
When it happens
Trigger: Calling the assign-menus tool with a menuIds array longer than orgBatchLimit (e.g. attempting to grant every menu of the system in one call).
Common situations: Bulk-provisioning a new super-admin role from a script; migrating permissions between environments in one shot; generating menuIds from a wide query without chunking.
Related errors
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/d18239274b9d417b.
Report an issue: GitHub.