{"record":{"id":"92d682b39b58773f","repo":"flipped-aurora/gin-vue-admin","slug":"apis-path","errorCode":null,"errorMessage":"apis 数组元素缺少 path 字段","messagePattern":"apis 数组元素缺少 path 字段","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mcp/role_api_batch_assigner.go","lineNumber":144,"sourceCode":"// 批内按 归一化path+method 去重\nfunc parseAPIItems(v any) ([]systemReq.CasbinInfo, error) {\n\tif v == nil {\n\t\treturn nil, nil\n\t}\n\tvar items []systemReq.CasbinInfo\n\n\tappendItem := func(path, method string) {\n\t\titems = append(items, systemReq.CasbinInfo{Path: path, Method: method})\n\t}\n\n\tswitch value := v.(type) {\n\tcase []any:\n\t\tfor _, entry := range value {\n\t\t\tswitch typed := entry.(type) {\n\t\t\tcase map[string]any:\n\t\t\t\tpath, _ := typed[\"path\"].(string)\n\t\t\t\tif strings.TrimSpace(path) == \"\" {\n\t\t\t\t\treturn nil, errors.New(\"apis 数组元素缺少 path 字段\")\n\t\t\t\t}\n\t\t\t\tmethod, _ := typed[\"method\"].(string)\n\t\t\t\tappendItem(path, method)\n\t\t\tcase string:\n\t\t\t\tpath, method, err := parseAPIItemString(typed)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tappendItem(path, method)\n\t\t\tdefault:\n\t\t\t\treturn nil, errors.New(\"apis 数组元素需为 {path,method} 对象或 \\\"METHOD /path\\\" 字符串\")\n\t\t\t}\n\t\t}\n\tcase string:\n\t\ttrimmed := strings.TrimSpace(value)\n\t\tif trimmed == \"\" {\n\t\t\treturn nil, nil\n\t\t}","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/mcp/role_api_batch_assigner.go#L126-L162","documentation":"parseAPIItems iterates the 'apis' array; each map[string]any element must carry a non-empty 'path' string. The error is thrown when an element is an object but its 'path' is missing, not a string, or blank after trimming.","triggerScenarios":"An apis element like {\"method\":\"GET\"} (no path), {\"path\":123}, or {\"path\":\"  \"}.","commonSituations":"Hand-written JSON payload with a renamed path field; client sending method only; pasting numeric IDs instead of route paths; mixed batches where some items conform and others do not.","solutions":["Add a non-empty string 'path' field to each object element","If the item is free-form text, format it as \"METHOD /path\" string instead of an object","Validate each item client-side for a non-empty string path before calling"],"exampleFix":"// before\nargs[\"apis\"] = []any{map[string]any{\"method\": \"GET\"}}\n// after\nargs[\"apis\"] = []any{map[string]any{\"path\": \"/api/user/list\", \"method\": \"GET\"}}","handlingStrategy":"validation","validationCode":"for (const item of apis) {\n  if (typeof item === \"object\" && item !== null && !Array.isArray(item)) {\n    if (typeof item.path !== \"string\" || item.path.trim() === \"\") {\n      throw new Error(\"每个对象元素必须包含非空 path 字段\")\n    }\n  }\n}","typeGuard":"function isApiItem(v: unknown): v is { path: string; method?: string } {\n  return typeof v === \"object\" && v !== null && !Array.isArray(v)\n    && typeof (v as any).path === \"string\" && (v as any).path.trim() !== \"\"\n}","tryCatchPattern":"try {\n  await callTool(\"role_api_batch_assigner\", { apis })\n} catch (e) {\n  if (String(e.message).includes(\"缺少 path 字段\")) {\n    // 修正该批次的违规项\n  }\n  throw e\n}","preventionTips":["Validate batch elements before submit with a shared zod/jsonschema definition","Reject mixed item structures from user input, or normalize to strings","Check the 'path' key exists on every object item"],"tags":["mcp","validation","missing-field","batch-input"],"backgroundTag":"batch-item-schema-mismatch","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}