flipped-aurora/gin-vue-admin · error
未找到 ID 为 %d 的用户(已扫描前 %d 条,大用户量场景请传 username 参数精确定位)
Error message
未找到 ID 为 %d 的用户(已扫描前 %d 条,大用户量场景请传 username 参数精确定位)
What it means
findUserByID exhausts its scan: upstream getUserList lacks ID filtering, so the tool scans up to 20 pages of 100 users (2000 records). If the target ID never appears (or the user is outside the caller's data-scope visibility), this error is returned with guidance to pass a username hint.
Source
Thrown at server/mcp/org_common.go:256
return nil, fmt.Errorf("获取用户列表失败: %w", err)
}
for i := range resp.Data.List {
if resp.Data.List[i].ID == userID {
return &resp.Data.List[i], nil
}
}
// hint 仅是加速命中的优化;username 为 LIKE 模糊匹配且只查首页,未命中(名不匹配或
// 命中过多致目标不在首页)时不误报,回退全量翻页扫描兜底
}
found, _, err := scanUsersByIDs(ctx, []uint{userID})
if err != nil {
return nil, err
}
if user, ok := found[userID]; ok {
return &user, nil
}
return nil, fmt.Errorf("未找到 ID 为 %d 的用户(已扫描前 %d 条,大用户量场景请传 username 参数精确定位)", userID, orgUserScanMaxPages*orgUserScanPageSize)
}
// requireNonEmptyList 语义化的必填列表校验
func requireNonEmptyList(ids []uint, name string) error {
if len(ids) == 0 {
return errors.New(name + " 参数是必需的,且至少包含一个ID")
}
return nil
}
// parseOptionalPositiveInt 解析可选的正整数分页参数,兼容数字与字符串两种形式
// (与本工具集"数字参数兼容字符串"的既定设计一致);缺省或非法时返回 def
func parseOptionalPositiveInt(v any, def int) int {
switch value := v.(type) {
case float64:
if value >= 1 {
return int(value)
}View on GitHub (pinned to 3136500ef3)
Solutions
- Pass the username parameter so the tool can locate the user precisely via the LIKE filter
- Verify the userId is correct and the user exists in the admin UI
- Check the user is within the MCP token's data-scope visible range
- Confirm the user has not been deleted
- If the deployment is very large and username unknown, look up the ID in the frontend first
Example fix
// before
{"userId": 8873}
// after
{"userId": 8873, "username": "zhangsan"} // precise locate, avoids 2000-row scan Defensive patterns
Strategy: validation
Validate before calling
// resolve the user first via a direct lookup, only call the assign tool with a confirmed ID + username
const user = await findUserByUsername(username)
if (!user) throw new Error('target user does not exist')
// then pass both: { userId: user.ID, username: user.username } Try / catch
try {
await callMcpTool('assign_user_org', args)
} catch (e) {
if (/未找到 ID 为 \d+ 的用户/.test(e.message)) {
// re-call with username hint, or verify the ID/data-scope visibility in the admin UI
}
} Prevention
- Always supply the username hint in deployments with >2000 users
- Validate userIds exist (and are data-scope visible for the token) before calling
- Keep environment-specific ID maps instead of hardcoding user IDs
When it happens
Trigger: Requesting an org operation on a userId whose record is not within the first 2000 visible rows of /user/getUserList, the user does not exist, or the row is hidden by the caller's data-scope permissions.
Common situations: Large deployments with >2000 users where the target user sits beyond the scan limit; userId typo or from another environment; data-scope engine filters the row out for this token; user soft-deleted.
Understand the failure class
Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.
Related errors
- 角色 %d 不存在或当前token无权查看
- 获取用户列表失败: %w
- 部门 %d 不存在,可先用 query_org_structure 查询部门树
- 岗位 %d 校验失败: %w
- dataScope 必须在 1-5 之间:1全部 2本部门及以下 3本部门 4仅本人 5自定义部门,收到 %d
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/1d06423c591ceb71.
Report an issue: GitHub.