{"record":{"id":"f370dace6100ee92","repo":"flipped-aurora/gin-vue-admin","slug":"d-structname","errorCode":null,"errorMessage":"模块 %d 的 structName 不能为空","messagePattern":"模块 (.+?) 的 structName 不能为空","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mcp/gva_execute.go","lineNumber":329,"sourceCode":"\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)\n\t\t\t}\n\t\t\tif len(moduleInfo.Fields) == 0 {\n\t\t\t\treturn fmt.Errorf(\"模块 %d 的 fields 不能为空，至少需要一个字段\", moduleIndex+1)","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/mcp/gva_execute.go#L311-L347","documentation":"validateExecutionPlan (server/mcp/gva_execute.go:329) rejects an ExecutionPlan when a module in modulesInfo has an empty structName. structName is the Go struct name for the generated model (upper camel case, e.g. UserInfo); the code generator cannot name the module's structs, files and tables without it. The module index in the message is 1-based.","triggerScenarios":"Calling gva_execute with needCreatedModules=true and a modulesInfo entry missing \"structName\" or passing an empty string — common when the LLM only filled package/tableName or used a lowercase/plain name that later got lost.","commonSituations":"LLM-generated plans omitting the struct name; clients mapping a different field name (e.g. modelName) into the payload; copy-pasted partial module entries from earlier rounds.","solutions":["Locate the module at the reported 1-based index in modulesInfo.","Set \"structName\" to an upper-camel-case Go name, e.g. \"UserInfo\".","Derive related fields consistently: humpPackageName from the struct's lower-camel form, tableName in snake_case.","Verify remaining required fields (package, tableName, description, abbreviation, packageName, humpPackageName, fields) are all present to avoid further validation rounds."],"exampleFix":"// before\n\"modulesInfo\":[{\"package\":\"user\",\"tableName\":\"users\",\"description\":\"用户管理\", ...}]\n// after\n\"modulesInfo\":[{\"package\":\"user\",\"structName\":\"User\",\"tableName\":\"users\",\"description\":\"用户管理\", ...}]","handlingStrategy":"validation","validationCode":"function validateStructNames(modulesInfo) {\n  modulesInfo?.forEach((m, i) => {\n    if (typeof m.structName !== 'string' || !m.structName) {\n      throw new Error(`module ${i + 1}: structName required (upper camel case, e.g. UserInfo)`)\n    }\n  })\n}","typeGuard":"function hasStructName(m) {\n  return typeof m?.structName === 'string' && /^[A-Z][A-Za-z0-9]*$/.test(m.structName)\n}","tryCatchPattern":"try {\n  return await callTool('gva_execute', { executionPlan: plan })\n} catch (e) {\n  const m = String(e.message).match(/模块 (\\d+) 的 structName 不能为空/)\n  if (m) {\n    plan.modulesInfo[Number(m[1]) - 1].structName = toUpperCamel(tableName) // derive and retry\n    return await callTool('gva_execute', { executionPlan: plan })\n  }\n  throw e\n}","preventionTips":["Derive structName from tableName via snake_case → UpperCamel conversion in your plan builder.","Keep structName, humpPackageName and packageName consistent with one naming pass.","Pre-validate module entries against the full required-field list before calling."],"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"}