{"record":{"id":"385c5b7e698b9b1e","repo":"iflytek/astron-agent","slug":"response-failed-empty-file","errorCode":"RESPONSE_FAILED","errorMessage":"Empty file","messagePattern":"Empty file","errorType":"validation","errorClass":"BusinessException","httpStatus":null,"severity":"warning","filePath":"console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/common/ImageService.java","lineNumber":41,"sourceCode":"    // Allowed Content-Types (extend as needed)\n    private static final String[] ALLOWED_TYPES = {\n            \"image/png\", \"image/jpeg\", \"image/jpg\", \"image/gif\", \"image/webp\", \"image/svg+xml\"\n    };\n\n    // Recommended minimal part size for MinIO/Amazon multipart upload: 5MB\n    private static final long MULTIPART_PART_SIZE = 5L * 1024 * 1024;\n\n    /**\n     * Upload an image and return an accessible URL (if the bucket policy is not public, consider\n     * returning the object key or a pre-signed URL instead).\n     *\n     * @param file multipart file to upload; must not be {@code null} or empty\n     * @return the object key (or URL depending on bucket policy) of the uploaded image\n     * @throws BusinessException if validation fails, upload fails, or an I/O error occurs\n     */\n    public String upload(MultipartFile file) {\n        if (file == null || file.isEmpty()) {\n            throw new BusinessException(ResponseEnum.RESPONSE_FAILED, \"Empty file\");\n        }\n\n        final String contentType = normalizeContentType(file.getContentType());\n        if (!isAllowedType(contentType)) {\n            throw new BusinessException(ResponseEnum.RESPONSE_FAILED, \"Unsupported content type: \" + contentType);\n        }\n\n        final long size = file.getSize();\n\n        final String original = file.getOriginalFilename();\n        final String safeName = buildSafeFileName(original, contentType);\n        final String objectKey = \"icon/user/\" + safeName;\n\n        try (InputStream in = file.getInputStream()) {\n            if (size > 0) {\n                // Known content length: prefer direct upload\n                s3UtilClient.putObject(objectKey, in, size, contentType);\n            } else {","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/common/ImageService.java#L23-L59","documentation":"ImageService.upload validates the incoming MultipartFile before doing any storage work and throws 'Empty file' when the file is null or isEmpty(). This is a deliberate input-validation failure — nothing reached S3/MinIO.","triggerScenarios":"Calling upload(null) or passing a MultipartFile with zero bytes — e.g. an image-upload endpoint hit with a missing file part, a form field posted without selecting a file, or a client sending Content-Length: 0.","commonSituations":"Frontend upload form submitting without a file selected; API consumers posting multipart requests where the file part name does not match what the controller binds; proxies stripping empty parts.","solutions":["Fix the client to actually attach a non-empty file to the multipart request (correct part name).","Validate file presence/size on the client side before submitting the form.","In the controller, reject the request with 400 and a clear message when the file part is missing rather than reaching the service.","If empty files should be tolerated, decide on a policy and handle them before calling upload()."],"exampleFix":"// before (caller)\nservice.upload(file); // file may be null/empty\n\n// after (caller)\nif (file == null || file.isEmpty()) {\n    throw new BusinessException(ResponseEnum.RESPONSE_FAILED, \"Please select an image to upload\");\n}\nservice.upload(file);","handlingStrategy":"validation","validationCode":"if (file == null || file.isEmpty()) {\n    throw new IllegalArgumentException(\"Please attach a non-empty image file\");\n}\nimageService.upload(file);","typeGuard":"static boolean isUploadable(MultipartFile f) {\n    return f != null && !f.isEmpty();\n}","tryCatchPattern":"try {\n    String key = imageService.upload(file);\n} catch (BusinessException e) {\n    if (\"Empty file\".equals(e.getMessage())) {\n        // return 400 Bad Request to the client\n    }\n    throw e;\n}","preventionTips":["Enforce required file parts at the controller layer (@RequestParam MultipartFile file with validation).","Validate file presence and size client-side before submitting the form.","Return 400 with a clear message when the multipart part is missing."],"tags":["validation","upload","multipart","java"],"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-15T23:17:13.987Z"}