{"record":{"id":"4929916b651e5b95","repo":"flipped-aurora/gin-vue-admin","slug":"mcp-492991","errorCode":null,"errorMessage":"mcp名称不能为空","messagePattern":"mcp名称不能为空","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/plugin/ai/service/sys_mcp.go","lineNumber":21,"sourceCode":"import (\n\t\"context\"\n\t\"errors\"\n\t\"strings\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\tsysModel \"github.com/flipped-aurora/gin-vue-admin/server/model/system\"\n\tautoModel \"github.com/flipped-aurora/gin-vue-admin/server/plugin/ai/model\"\n\tautoReq \"github.com/flipped-aurora/gin-vue-admin/server/plugin/ai/model/request\"\n\tautoRes \"github.com/flipped-aurora/gin-vue-admin/server/plugin/ai/model/response\"\n\t\"gorm.io/gorm\"\n)\n\ntype mcService struct{}\n\nfunc (s *mcService) CreateMcp(ctx context.Context, req autoReq.CreateSysMcpRequest) (autoModel.SysMcp, error) {\n\tname := strings.TrimSpace(req.Name)\n\tif name == \"\" {\n\t\treturn autoModel.SysMcp{}, errors.New(\"mcp名称不能为空\")\n\t}\n\tif exists, err := s.sysMcpNameExists(ctx, name, 0); err != nil {\n\t\treturn autoModel.SysMcp{}, err\n\t} else if exists {\n\t\treturn autoModel.SysMcp{}, errors.New(\"存在同名MCP\")\n\t}\n\tentity := autoModel.SysMcp{\n\t\tName:          name,\n\t\tDisplayName:   strings.TrimSpace(req.DisplayName),\n\t\tDescription:   strings.TrimSpace(req.Description),\n\t\tStatus:        strings.TrimSpace(req.Status),\n\t\tVersion:       strings.TrimSpace(req.Version),\n\t\tScenariosJSON: req.ScenariosJSON,\n\t}\n\tapplySysMcpDefaults(&entity)\n\tif err := global.GVA_DB.WithContext(ctx).Create(&entity).Error; err != nil {\n\t\treturn autoModel.SysMcp{}, err\n\t}","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/plugin/ai/service/sys_mcp.go#L3-L39","documentation":"CreateMcp trims req.Name and rejects empty values with this error before any insert: every MCP record must have a non-empty name. The trimmed name is then also used for the uniqueness check and becomes the stored Name.","triggerScenarios":"Calling CreateMcp with Name set to \"\" or whitespace only, e.g. an unmarshaled request where the name field was absent.","commonSituations":"MCP creation dialog submitted with the name input left blank; API clients building the struct programmatically and forgetting Name; automated seeds that fill DisplayName/Description but not Name.","solutions":["Provide a non-empty Name in the CreateSysMcpRequest","Trim and validate req.Name on the client before calling","Make the name field required in the UI form","Add a struct-tag or DTO-level required validation to fail earlier"],"exampleFix":"// before\nreq := autoReq.CreateSysMcpRequest{Name: \"  \", DisplayName: \"My MCP\"}\nmcpService.CreateMcp(ctx, req)\n// after\nreq := autoReq.CreateSysMcpRequest{Name: strings.TrimSpace(\"my-mcp\"), DisplayName: \"My MCP\"}\nif req.Name == \"\" { return errors.New(\"mcp name required\") }\nmcpService.CreateMcp(ctx, req)","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(req.Name) == \"\" {\n    return errors.New(\"MCP name is required\")\n}","typeGuard":"func hasMcpName(req autoReq.CreateSysMcpRequest) bool {\n    return strings.TrimSpace(req.Name) != \"\"\n}","tryCatchPattern":"mcp, err := mcpService.CreateMcp(ctx, req)\nif err != nil {\n    if err.Error() == \"mcp名称不能为空\" {\n        return fmt.Errorf(\"provide a name for the MCP\")\n    }\n    return err\n}","preventionTips":["Mark the name field required in the creation form","Trim inputs before sending","Validate required fields in the DTO before calling the service","Never rely on DisplayName as a substitute for Name"],"tags":["validation","go","plugin-ai","mcp"],"backgroundTag":"required-field-missing","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}