{"record":{"id":"a54e2eaff7a391f4","repo":"iflytek/astron-agent","slug":"s3-upload-error","errorCode":"S3_UPLOAD_ERROR","errorMessage":"S3 upload error","messagePattern":"S3 upload error","errorType":"error_code","errorClass":"BusinessException","httpStatus":null,"severity":"error","filePath":"console/backend/commons/src/main/java/com/iflytek/astron/console/commons/util/S3ClientUtil.java","lineNumber":698,"sourceCode":"    }\n\n    /**\n     * Upload object (stream). Caller is responsible for closing the input stream.\n     *\n     * @param bucketName target bucket\n     * @param objectKey object key (path)\n     * @param contentType MIME type, e.g., \"application/octet-stream\" or a specific type\n     * @param inputStream input stream\n     * @param objectSize total object size (-1 if unknown, provide partSize)\n     * @param partSize part size (required when objectSize=-1, recommend >= 10MB)\n     * @return uploaded object URL\n     */\n    public String uploadObject(String bucketName, String objectKey, String contentType, InputStream inputStream,\n            long objectSize, long partSize) {\n        // Validate parameters\n        if (bucketName == null || bucketName.trim().isEmpty()) {\n            log.error(\"Bucket name cannot be null or empty\");\n            throw new BusinessException(ResponseEnum.S3_UPLOAD_ERROR);\n        }\n        if (objectKey == null || objectKey.trim().isEmpty()) {\n            log.error(\"Object key cannot be null or empty\");\n            throw new BusinessException(ResponseEnum.S3_UPLOAD_ERROR);\n        }\n        if (inputStream == null) {\n            log.error(\"Input stream cannot be null\");\n            throw new BusinessException(ResponseEnum.S3_UPLOAD_ERROR);\n        }\n\n        try {\n            PutObjectArgs.Builder builder = PutObjectArgs.builder()\n                    .bucket(bucketName)\n                    .object(objectKey)\n                    .stream(inputStream, objectSize, partSize);\n\n            if (contentType != null && !contentType.isEmpty()) {\n                builder.contentType(contentType);","sourceCodeStart":680,"sourceCodeEnd":716,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/commons/src/main/java/com/iflytek/astron/console/commons/util/S3ClientUtil.java#L680-L716","documentation":"uploadObject validates parameters before the MinIO put and throws BusinessException(S3_UPLOAD_ERROR) when bucketName is null or blank. Unlike the config errors this uses the dedicated S3_UPLOAD_ERROR code so callers can distinguish upload misuse from generic server failures. No data is transferred.","triggerScenarios":"Calling uploadObject with an empty/null bucket name — usually an unset per-upload bucket parameter or a config value that resolved to blank.","commonSituations":"Caller passes a tenant bucket variable that was never initialized; controller forwards an empty bucket field from the request; refactor renamed the bucket field leaving null.","solutions":["Pass a valid non-blank bucket name (default to the configured default bucket when the caller has none)","Validate the bucket parameter at the API boundary before invoking uploadObject","Check the log 'Bucket name cannot be null or empty' to locate the offending call site"],"exampleFix":"// before\ns3ClientUtil.uploadObject(bucket, key, contentType, stream, size, partSize); // bucket may be null\n// after\nString targetBucket = (bucket == null || bucket.isBlank()) ? s3ClientUtil.getDefaultBucket() : bucket;\ns3ClientUtil.uploadObject(targetBucket, key, contentType, stream, size, partSize);","handlingStrategy":"validation","validationCode":"boolean validBucket(String b) { return b != null && !b.isBlank(); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default to the configured default bucket when a caller bucket is absent","Validate bucket at the API boundary","Never thread raw request fields into the S3 util unchecked"],"tags":["s3","upload","validation"],"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"}