{"record":{"id":"75c906d96e7fadb7","repo":"alibaba/nacos","slug":"data-empty-75c906","errorCode":"DATA_EMPTY","errorMessage":"File is required","messagePattern":"File is required","errorType":"validation","errorClass":"NacosApiException","httpStatus":400,"severity":"error","filePath":"ai/src/main/java/com/alibaba/nacos/ai/utils/SkillRequestUtil.java","lineNumber":385,"sourceCode":"                ErrorCode.PARAMETER_VALIDATE_ERROR,\n                \"skillCard namespaceId must match request namespaceId\");\n        }\n        skill.setNamespaceId(namespaceId);\n    }\n    \n    /**\n     * Validate uploaded skill zip file and extract bytes.\n     *\n     * <p>Validates the file is not null/empty, checks file size against the maximum limit,\n     * and extracts the file bytes. This method is shared by both admin and console upload endpoints.</p>\n     *\n     * @param file the uploaded multipart file\n     * @return the file bytes\n     * @throws NacosException if validation fails or file reading fails\n     */\n    public static byte[] validateAndExtractZipBytes(MultipartFile file) throws NacosException {\n        if (file == null || file.isEmpty()) {\n            throw new NacosApiException(NacosException.INVALID_PARAM, ErrorCode.DATA_EMPTY,\n                \"File is required\");\n        }\n        long maxUploadBytes = SkillZipParser.resolveMaxUploadBytes();\n        if (file.getSize() > maxUploadBytes) {\n            throw new NacosApiException(NacosException.INVALID_PARAM,\n                ErrorCode.PARAMETER_VALIDATE_ERROR,\n                \"Skill zip size must not exceed \"\n                    + (maxUploadBytes / 1024 / 1024)\n                    + \"MB, current: \" + (file.getSize() / 1024 / 1024) + \"MB\");\n        }\n        try {\n            return file.getBytes();\n        } catch (IOException e) {\n            throw new NacosApiException(NacosException.SERVER_ERROR, ErrorCode.PARSING_DATA_FAILED,\n                \"Failed to read file: \" + e.getMessage());\n        }\n    }\n}","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/ai/src/main/java/com/alibaba/nacos/ai/utils/SkillRequestUtil.java#L367-L403","documentation":"Thrown by validateAndExtractZipBytes when the uploaded MultipartFile is null or isEmpty() returns true. This is the entry-point validation for skill ZIP upload endpoints (both admin and console). The error uses ErrorCode.DATA_EMPTY with HTTP 400 to indicate no file was provided in the multipart request.","triggerScenarios":"POST to a skill upload/import endpoint (admin or console) where no file part is included in the multipart form data, or the file part is present but has zero bytes (empty file). The MultipartFile parameter resolves to null when the part name is wrong or absent.","commonSituations":"Frontend form does not include a file input or the file input is empty when the form is submitted; the multipart part name does not match the controller parameter name; curl command omits the -F file=@... argument; the file was selected but the browser failed to read it (permission denied locally).","solutions":["Ensure the multipart form data includes a non-empty file part with the correct part name expected by the controller.","Verify the file was actually selected and readable before form submission — add client-side validation for non-empty file selection.","For curl testing, include the file argument: curl -F 'file=@skill.zip' ...","Check that the Content-Type header is multipart/form-data and the file part name matches the @RequestParam(\"file\") annotation."],"exampleFix":"// before — curl command missing the file argument\ncurl -X POST http://localhost:8848/v3/admin/ai/skill/import?namespaceId=public\n\n// after — file part included\ncurl -X POST -F 'file=@./skill.zip' http://localhost:8848/v3/admin/ai/skill/import?namespaceId=public","handlingStrategy":"validation","validationCode":"// Check file is present and non-empty before upload\nif (file == null || file.isEmpty()) {\n    throw new IllegalArgumentException(\"A non-empty ZIP file is required\");\n}","typeGuard":"// JavaScript (frontend) type guard\nfunction isValidFileUpload(file) {\n    return file != null && file instanceof File && file.size > 0;\n}","tryCatchPattern":"try {\n    byte[] bytes = SkillRequestUtil.validateAndExtractZipBytes(file);\n} catch (NacosApiException e) {\n    if (ErrorCode.DATA_EMPTY.equals(e.getErrDetail())) {\n        return ResponseEntity.badRequest().body(\"No file uploaded. Please select a ZIP file.\");\n    }\n    throw e;\n}","preventionTips":["Add client-side validation to disable the submit button until a non-empty file is selected.","Verify the multipart form field name matches the controller @RequestParam name.","For curl testing, always include the -F file=@path argument."],"tags":["skill","file-upload","data-empty","multipart"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}