{"record":{"id":"2a5ce3fba87a5f78","repo":"flipped-aurora/gin-vue-admin","slug":"packageinfo-template-package-plugin","errorCode":null,"errorMessage":"packageInfo.template 必须是 'package' 或 'plugin'","messagePattern":"packageInfo\\.template 必须是 'package' 或 'plugin'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mcp/gva_execute.go","lineNumber":309,"sourceCode":"\t\treturn errors.New(\"packageName 不能为空\")\n\t}\n\tif plan.PackageType != \"package\" && plan.PackageType != \"plugin\" {\n\t\treturn errors.New(\"packageType 必须是 'package' 或 'plugin'\")\n\t}\n\n\tif plan.NeedCreatedPackage && plan.PackageInfo != nil && plan.PackageType != plan.PackageInfo.Template {\n\t\treturn errors.New(\"packageType 和 packageInfo.template 必须保持一致\")\n\t}\n\n\tif plan.NeedCreatedPackage {\n\t\tif plan.PackageInfo == nil {\n\t\t\treturn errors.New(\"当 needCreatedPackage=true 时，packageInfo 不能为空\")\n\t\t}\n\t\tif plan.PackageInfo.PackageName == \"\" {\n\t\t\treturn errors.New(\"packageInfo.packageName 不能为空\")\n\t\t}\n\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}","sourceCodeStart":291,"sourceCodeEnd":327,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/mcp/gva_execute.go#L291-L327","documentation":"validateExecutionPlan requires that packageInfo.template, when package creation is requested, is exactly \"package\" or \"plugin\" — the same enum as the top-level packageType, because this field drives the code-generation template selection. Other values (including different casing) are rejected.","triggerScenarios":"executionPlan with needCreatedPackage=true and packageInfo.template set to \"\", \"Plugin\", \"module\", or any string other than the exact lowercase literals \"package\"/\"plugin\".","commonSituations":"UI dropdown defaulting to an empty value; LLM writing a human-friendly template name; older plan format using different template identifiers that no longer match the whitelist.","solutions":["Set packageInfo.template to exactly \"package\" or \"plugin\" (lowercase).","Sync it with the top-level packageType (they must match — see error 23).","Normalize/validate the value against the whitelist before sending.","Ensure the source of the value (form/config) only offers these two options."],"exampleFix":"// before\npackageInfo: { packageName: \"order-center\", template: \"Plugin\", label: \"订单中心\", desc: \"...\" }\n\n// after\npackageInfo: { packageName: \"order-center\", template: \"plugin\", label: \"订单中心\", desc: \"...\" }","handlingStrategy":"validation","validationCode":"function requireValidNestedTemplate(plan) {\n  if (plan.needCreatedPackage && !['package', 'plugin'].includes(plan.packageInfo?.template)) {\n    throw new Error(`packageInfo.template must be 'package' or 'plugin', got: ${plan.packageInfo?.template}`);\n  }\n  return plan;\n}","typeGuard":"function hasValidNestedTemplate(plan) {\n  return !plan.needCreatedPackage || plan.packageInfo?.template === 'package' || plan.packageInfo?.template === 'plugin';\n}","tryCatchPattern":"try {\n  return await callTool('gva_execute', { executionPlan: plan });\n} catch (err) {\n  if (String(err.message).includes(\"packageInfo.template 必须是\")) {\n    const normalized = String(plan.packageInfo.template).toLowerCase();\n    plan.packageInfo.template = ['package', 'plugin'].includes(normalized) ? normalized : plan.packageType;\n    return callTool('gva_execute', { executionPlan: plan });\n  }\n  throw err;\n}","preventionTips":["Reuse the same enum/constant for packageInfo.template as for packageType","Set template: packageType when constructing packageInfo so they never diverge","Restrict template inputs in UIs to the two allowed literals"],"tags":["mcp","validation","enum","go"],"backgroundTag":"invalid-enum-value","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}