{"record":{"id":"88a5857120b09da2","repo":"flipped-aurora/gin-vue-admin","slug":"packageinfo-desc","errorCode":null,"errorMessage":"packageInfo.desc 不能为空","messagePattern":"packageInfo\\.desc 不能为空","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mcp/gva_execute.go","lineNumber":315,"sourceCode":"\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}\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}","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/mcp/gva_execute.go#L297-L333","documentation":"packageInfo.desc is a required description used in generated package/plugin metadata. validateExecutionPlan rejects an empty Desc so every created package ships with meaningful documentation text.","triggerScenarios":"executionPlan with needCreatedPackage=true and packageInfo.desc equal to \"\" or omitted.","commonSituations":"Same pattern as the label check: plans auto-generated by an LLM skipping the description, or a form where desc was optional client-side; copying packageInfo from an example and deleting desc.","solutions":["Set packageInfo.desc to a one-line description of the package/plugin.","Generate a sensible default (e.g. \"<label> 插件\") when no explicit description exists.","Mark desc as required in whatever UI builds the plan.","Validate required packageInfo fields client-side before invoking."],"exampleFix":"// before\npackageInfo: { packageName: \"order-center\", template: \"plugin\", label: \"订单中心\" }\n\n// after\npackageInfo: { packageName: \"order-center\", template: \"plugin\", label: \"订单中心\", desc: \"订单中心管理插件\" }","handlingStrategy":"validation","validationCode":"function requireDesc(plan) {\n  if (plan.needCreatedPackage && !plan.packageInfo?.desc?.trim()) {\n    throw new Error('packageInfo.desc is required');\n  }\n  return plan;\n}","typeGuard":"function hasPackageDesc(plan) {\n  return !plan.needCreatedPackage || (typeof plan.packageInfo?.desc === 'string' && plan.packageInfo.desc.trim().length > 0);\n}","tryCatchPattern":"try {\n  return await callTool('gva_execute', { executionPlan: plan });\n} catch (err) {\n  if (String(err.message).includes('packageInfo.desc 不能为空')) {\n    plan.packageInfo.desc = `${plan.packageInfo.label} 插件`; // generated default description\n    return callTool('gva_execute', { executionPlan: plan });\n  }\n  throw err;\n}","preventionTips":["Make desc a required input in plan-building UIs","Generate a default description from label when not supplied","Run a full packageInfo completeness check before every gva_execute call"],"tags":["mcp","validation","go","execution-plan"],"backgroundTag":"missing-required-field","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}