{"record":{"id":"1d7420240f125a56","repo":"iflytek/astron-agent","slug":"8322-toolbox-name-empty","errorCode":"8322","errorMessage":"toolbox.name.empty","messagePattern":"toolbox\\.name\\.empty","errorType":"error_code","errorClass":"BusinessException","httpStatus":null,"severity":"error","filePath":"console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/controller/tool/ToolBoxController.java","lineNumber":34,"sourceCode":"\nimport java.util.List;\nimport java.util.Map;\n\n@RestController\n@RequestMapping(\"/tool\")\n@Slf4j\n@ResponseResultBody\n@Tag(name = \"Plugin Management\")\npublic class ToolBoxController {\n    @Resource\n    ToolBoxService toolBoxService;\n\n    @PostMapping(\"/create-tool\")\n    @Operation(summary = \"Create plugin\")\n    @SpacePreAuth(key = \"ToolBoxController_createTool_POST\")\n    public Object createTool(@RequestBody ToolBoxDto toolBoxDto) {\n        if (toolBoxDto.getName() == null) {\n            throw new BusinessException(ResponseEnum.TOOLBOX_NAME_EMPTY);\n        }\n        if (toolBoxDto.getDescription() == null) {\n            throw new BusinessException(ResponseEnum.TOOLBOX_NAME_EMPTY);\n        }\n        return toolBoxService.createTool(toolBoxDto);\n    }\n\n    @PostMapping(\"/temporary-tool\")\n    @Operation(summary = \"Temporarily save plugin\")\n    @SpacePreAuth(key = \"ToolBoxController_temporaryTool_POST\")\n    public Object temporaryTool(@RequestBody ToolBoxDto toolBoxDto) {\n        if (toolBoxDto.getName() == null) {\n            throw new BusinessException(ResponseEnum.TOOLBOX_NAME_EMPTY);\n        }\n        return toolBoxService.temporaryTool(toolBoxDto);\n    }\n\n    @PutMapping(\"/update-tool\")","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/controller/tool/ToolBoxController.java#L16-L52","documentation":"TOOLBOX_NAME_EMPTY (code 8322) thrown by ToolBoxController.createTool when the request body's name field is null. The controller performs null checks on name and description before calling toolBoxService.createTool. Note the same enum is reused for a missing description, so 'toolbox.name.empty' can actually mean either field is missing.","triggerScenarios":"POST /create-tool with a JSON body lacking the name field (e.g. {\"description\":\"my plugin\"}) — or, per line 37, lacking the description field.","commonSituations":"Frontend form submitted before the name input is filled; client builds the DTO dynamically and omits null keys; renamed API fields after a version change so the client still sends an old field name.","solutions":["Include both name and description (non-null) in the create-tool request body.","Add required-field checks client-side before submitting the form.","Server-side, distinguish the two failures: throw TOOLBOX_NAME_EMPTY for name and a dedicated TOOLBOX_DESCRIPTION_EMPTY enum for description.","Add @NotBlank bean-validation annotations on ToolBoxDto so Spring returns a 400 with field-level messages."],"exampleFix":"// before\n{\"description\": \"my plugin\"}\n// after\n{\"name\": \"my-plugin\", \"description\": \"my plugin\"}","handlingStrategy":"validation","validationCode":"function canCreateTool(dto) {\n  return dto != null && dto.name != null && dto.description != null;\n}","typeGuard":"const hasName = (dto) => typeof dto?.name === 'string' && dto.name.trim().length > 0;","tryCatchPattern":"try {\n  await api.createTool(dto);\n} catch (e) {\n  if (e.code === 8322) {\n    form.name.$error = !dto.name;\n    form.description.$error = !dto.description;\n  } else throw e;\n}","preventionTips":["Mark both name and description as required in the create form.","Block submit until required fields pass validation.","Add @NotBlank on ToolBoxDto.name/description for server-side bean validation.","Don't send objects with null keys stripped — validate before serialization."],"tags":["validation","missing-field","plugin-toolbox"],"backgroundTag":"empty-required-field","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}