{"record":{"id":"ed991bea5504a3a1","repo":"flipped-aurora/gin-vue-admin","slug":"packagetype-package-plugin","errorCode":null,"errorMessage":"packageType 必须是 'package' 或 'plugin'","messagePattern":"packageType 必须是 'package' 或 'plugin'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mcp/gva_execute.go","lineNumber":294,"sourceCode":"\tresponseJSON, err := json.MarshalIndent(response, \"\", \"  \")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"序列化结果失败: %v\", err)\n\t}\n\n\treturn &mcp.CallToolResult{\n\t\tContent: []mcp.Content{\n\t\t\tmcp.NewTextContent(fmt.Sprintf(\"执行结果：\\n\\n%s%s\", string(responseJSON), reviewMessage)),\n\t\t},\n\t}, nil\n}\n\n// validateExecutionPlan 验证执行计划的完整性\nfunc (g *GVAExecutor) validateExecutionPlan(ctx context.Context, plan *ExecutionPlan) error {\n\tif plan.PackageName == \"\" {\n\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 不能为空\")","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/mcp/gva_execute.go#L276-L312","documentation":"validateExecutionPlan enforces that plan.PackageType is exactly one of the two supported template kinds: \"package\" or \"plugin\". Any other value (empty, different casing, or an arbitrary string) is rejected because the downstream generator can only dispatch to those two workflows.","triggerScenarios":"executionPlan contains `packageType` set to \"\", \"Package\", \"packages\", \"api\", or any value other than the exact lowercase literals \"package\" or \"plugin\".","commonSituations":"Case-sensitivity mistakes (\"Plugin\"); LLM-generated plans inventing a type; older client code using a deprecated type name that no longer matches the accepted literals.","solutions":["Set `packageType` to exactly \"package\" or \"plugin\" (lowercase).","Normalize the value before sending: strings.ToLower + whitelist check.","If the type is chosen dynamically, validate against [\"package\",\"plugin\"] and reject other values early.","If an additional type is genuinely needed, extend validateExecutionPlan's whitelist in server/mcp/gva_execute.go."],"exampleFix":"// before\nconst plan = { packageName: \"order-center\", packageType: \"Plugin\" }\n\n// after\nconst plan = { packageName: \"order-center\", packageType: \"plugin\" }","handlingStrategy":"validation","validationCode":"const PACKAGE_TYPES = ['package', 'plugin'];\nfunction requireValidPackageType(plan) {\n  if (!PACKAGE_TYPES.includes(plan?.packageType)) {\n    throw new Error(`packageType must be one of ${PACKAGE_TYPES.join('|')}, got: ${plan?.packageType}`);\n  }\n  return plan;\n}","typeGuard":"function isPackageType(v) {\n  return v === 'package' || v === 'plugin';\n}","tryCatchPattern":"try {\n  return await callTool('gva_execute', { executionPlan: plan });\n} catch (err) {\n  if (String(err.message).includes(\"packageType 必须是\")) {\n    const normalized = String(plan.packageType).toLowerCase();\n    plan.packageType = isPackageType(normalized) ? normalized : 'package';\n    return callTool('gva_execute', { executionPlan: plan });\n  }\n  throw err;\n}","preventionTips":["Use a shared enum/constant for packageType instead of free-form strings","Lowercase-normalize input before assigning","Restrict plan-building UIs to a dropdown with exactly these two options"],"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"}