{"record":{"id":"0f899c96a3ed8616","repo":"flipped-aurora/gin-vue-admin","slug":"api","errorCode":null,"errorMessage":"没有要创建的API","messagePattern":"没有要创建的API","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mcp/api_creator.go","lineNumber":100,"sourceCode":"\t\tif !ok || apiGroup == \"\" {\n\t\t\treturn nil, errors.New(\"apiGroup 参数是必需的\")\n\t\t}\n\n\t\tmethod := \"POST\"\n\t\tif value, ok := args[\"method\"].(string); ok && value != \"\" {\n\t\t\tmethod = value\n\t\t}\n\n\t\tapis = append(apis, ApiCreateRequest{\n\t\t\tPath:        path,\n\t\t\tDescription: description,\n\t\t\tApiGroup:    apiGroup,\n\t\t\tMethod:      method,\n\t\t})\n\t}\n\n\tif len(apis) == 0 {\n\t\treturn nil, errors.New(\"没有要创建的API\")\n\t}\n\n\tresponses := make([]ApiCreateResponse, 0, len(apis))\n\tsuccessCount := 0\n\n\tfor _, apiReq := range apis {\n\t\t// 批量模式给缺省 method 兜底 POST,与单条模式及 schema 默认值一致;\n\t\t// 否则空 method 会被上游 ApiVerify 判\"Method 不能为空\"导致该条静默失败\n\t\tif apiReq.Method == \"\" {\n\t\t\tapiReq.Method = \"POST\"\n\t\t}\n\t\t// createApi 现回传创建后的实体(含自增 ID),直接取用,免去此前逐条回查 getApiList 的 2N 次调用\n\t\tcreateResp, err := postUpstream[system.SysApi](ctx, \"/api/createApi\", system.SysApi{\n\t\t\tPath:        apiReq.Path,\n\t\t\tDescription: apiReq.Description,\n\t\t\tApiGroup:    apiReq.ApiGroup,\n\t\t\tMethod:      apiReq.Method,\n\t\t})","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/mcp/api_creator.go#L82-L118","documentation":"Thrown by ApiCreator's Handle after argument parsing when neither the bulk \"apis\" array nor the single-API fields produced any API entries, i.e. len(apis) == 0. This guards against a no-op tool call that would otherwise return an empty success response.","triggerScenarios":"Calling api_creator with an \"apis\" argument that parses to an empty JSON array (\"[]\"), or with no valid API-defining arguments at all.","commonSituations":"Agents sending \"apis\": \"[]\" placeholders; upstream code serializing an empty slice to the apis argument; callers passing neither apis nor the individual path/description/apiGroup fields.","solutions":["Populate the \"apis\" JSON array with at least one API object (path, description, apiGroup, optional method).","If only one API is needed, provide the individual path/description/apiGroup arguments instead.","Fix upstream serialization so an empty list is not sent; skip the tool call entirely when there is nothing to create."],"exampleFix":"// before\n{\"arguments\": {\"apis\": \"[]\"}}\n// after\n{\"arguments\": {\"apis\": \"[{\\\"path\\\":\\\"/user/list\\\",\\\"description\\\":\\\"获取用户列表\\\",\\\"apiGroup\\\":\\\"user\\\",\\\"method\\\":\\\"POST\\\"}]\"}}","handlingStrategy":"validation","validationCode":"let apis = JSON.parse(args.apis || \"[]\")\nif (!Array.isArray(apis) || apis.length === 0) {\n  throw new Error(\"api_creator called with no APIs to create; skipping\")\n}","typeGuard":"function hasApis(args) {\n  if (typeof args.apis !== \"string\") return false\n  try {\n    const parsed = JSON.parse(args.apis)\n    return Array.isArray(parsed) && parsed.length > 0\n  } catch {\n    return false\n  }\n}","tryCatchPattern":"try {\n  await callTool(\"api_creator\", { apis })\n} catch (e) {\n  if (e.message.includes(\"没有要创建的API\")) {\n    // nothing to create — return early instead of retrying\n  }\n}","preventionTips":["Check apis.length > 0 before invoking the tool.","Skip the tool call entirely when the batch is empty.","Ensure serializers do not emit \"[]\" placeholders for empty batches."],"tags":["mcp","empty-input","validation"],"backgroundTag":"empty-payload-rejected","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}