{"record":{"id":"c03f9fe2b09631a5","repo":"flipped-aurora/gin-vue-admin","slug":"d-package","errorCode":null,"errorMessage":"模块 %d 的 package 不能为空","messagePattern":"模块 (.+?) 的 package 不能为空","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mcp/gva_execute.go","lineNumber":326,"sourceCode":"\t\tif plan.PackageInfo.Template != \"package\" && plan.PackageInfo.Template != \"plugin\" {\n\t\t\treturn errors.New(\"packageInfo.template 必须是 'package' 或 'plugin'\")\n\t\t}\n\t\tif plan.PackageInfo.Label == \"\" {\n\t\t\treturn errors.New(\"packageInfo.label 不能为空\")\n\t\t}\n\t\tif plan.PackageInfo.Desc == \"\" {\n\t\t\treturn errors.New(\"packageInfo.desc 不能为空\")\n\t\t}\n\t}\n\n\tif plan.NeedCreatedModules {\n\t\tif len(plan.ModulesInfo) == 0 {\n\t\t\treturn errors.New(\"当 needCreatedModules=true 时，modulesInfo 不能为空\")\n\t\t}\n\n\t\tfor moduleIndex, moduleInfo := range plan.ModulesInfo {\n\t\t\tif moduleInfo.Package == \"\" {\n\t\t\t\treturn fmt.Errorf(\"模块 %d 的 package 不能为空\", moduleIndex+1)\n\t\t\t}\n\t\t\tif moduleInfo.StructName == \"\" {\n\t\t\t\treturn fmt.Errorf(\"模块 %d 的 structName 不能为空\", moduleIndex+1)\n\t\t\t}\n\t\t\tif moduleInfo.TableName == \"\" {\n\t\t\t\treturn fmt.Errorf(\"模块 %d 的 tableName 不能为空\", moduleIndex+1)\n\t\t\t}\n\t\t\tif moduleInfo.Description == \"\" {\n\t\t\t\treturn fmt.Errorf(\"模块 %d 的 description 不能为空\", moduleIndex+1)\n\t\t\t}\n\t\t\tif moduleInfo.Abbreviation == \"\" {\n\t\t\t\treturn fmt.Errorf(\"模块 %d 的 abbreviation 不能为空\", moduleIndex+1)\n\t\t\t}\n\t\t\tif moduleInfo.PackageName == \"\" {\n\t\t\t\treturn fmt.Errorf(\"模块 %d 的 packageName 不能为空\", moduleIndex+1)\n\t\t\t}\n\t\t\tif moduleInfo.HumpPackageName == \"\" {\n\t\t\t\treturn fmt.Errorf(\"模块 %d 的 humpPackageName 不能为空\", moduleIndex+1)","sourceCodeStart":308,"sourceCodeEnd":344,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/mcp/gva_execute.go#L308-L344","documentation":"validateExecutionPlan (server/mcp/gva_execute.go:326) rejects an ExecutionPlan when a module in modulesInfo has an empty package field. The message indexes modules from 1 (模块 %d), so \"模块 1\" is the first element. The package field names which existing autocode package the module's code belongs to; without it, generated code cannot be placed.","triggerScenarios":"Calling gva_execute with needCreatedModules=true and a modulesInfo entry lacking the \"package\" key or passing \"package\": \"\" — typically the LLM omitted it or confused it with packageName.","commonSituations":"LLM-generated plans that fill structName/tableName but skip package; confusion between the module's package field and packageName (file name) or the plan-level packageName; copying partial examples from older docs.","solutions":["Locate the module at the reported index (1-based) in modulesInfo.","Set its \"package\" field to the target package name (lowercase-leading, e.g. \"userInfo\").","Run gva_analyze first and copy the packageName from an existing package in the snapshot.","While editing, also supply the other required module fields (structName, tableName, description, abbreviation, packageName, humpPackageName, fields) to pass validation in one round."],"exampleFix":"// before\n\"modulesInfo\":[{\"structName\":\"User\",\"tableName\":\"users\", ...}]\n// after\n\"modulesInfo\":[{\"package\":\"user\",\"structName\":\"User\",\"tableName\":\"users\", ...}]","handlingStrategy":"validation","validationCode":"function validateModulePackage(modulesInfo) {\n  return modulesInfo?.every((m, i) => {\n    if (typeof m.package !== 'string' || !m.package) throw new Error(`module ${i + 1}: package required (lowercase-leading, from gva_analyze snapshot)`)\n    return true\n  })\n}","typeGuard":"function hasPackage(m) {\n  return typeof m?.package === 'string' && m.package.trim().length > 0\n}","tryCatchPattern":"try {\n  return await callTool('gva_execute', { executionPlan: plan })\n} catch (e) {\n  const m = String(e.message).match(/模块 (\\d+) 的 package 不能为空/)\n  if (m) {\n    plan.modulesInfo[Number(m[1]) - 1].package = targetPackage // fill and retry\n    return await callTool('gva_execute', { executionPlan: plan })\n  }\n  throw e\n}","preventionTips":["Source the package value from a gva_analyze snapshot, never freehand.","Don't confuse module.package with plan-level packageName or module.packageName.","Validate every module's required keys before dispatching the tool call."],"tags":["mcp","validation","autocode","missing-field","go"],"backgroundTag":"missing-required-field","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}