iflytek/astron-agent · error · BusinessException

S3_UPLOAD_ERROR

S3_UPLOAD_ERROR

Error message

S3 upload error

What it means

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.

Solutions

  1. Pass a valid non-blank bucket name (default to the configured default bucket when the caller has none)
  2. Validate the bucket parameter at the API boundary before invoking uploadObject
  3. Check the log 'Bucket name cannot be null or empty' to locate the offending call site

Example fix

// before
s3ClientUtil.uploadObject(bucket, key, contentType, stream, size, partSize); // bucket may be null
// after
String targetBucket = (bucket == null || bucket.isBlank()) ? s3ClientUtil.getDefaultBucket() : bucket;
s3ClientUtil.uploadObject(targetBucket, key, contentType, stream, size, partSize);
Defensive patterns

Strategy: validation

Validate before calling

boolean validBucket(String b) { return b != null && !b.isBlank(); }

Prevention

When it happens

Trigger: Calling uploadObject with an empty/null bucket name — usually an unset per-upload bucket parameter or a config value that resolved to blank.

Common situations: 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.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/a54e2eaff7a391f4. Report an issue: GitHub.

Appendix: source

Thrown at console/backend/commons/src/main/java/com/iflytek/astron/console/commons/util/S3ClientUtil.java:698

    }

    /**
     * Upload object (stream). Caller is responsible for closing the input stream.
     *
     * @param bucketName target bucket
     * @param objectKey object key (path)
     * @param contentType MIME type, e.g., "application/octet-stream" or a specific type
     * @param inputStream input stream
     * @param objectSize total object size (-1 if unknown, provide partSize)
     * @param partSize part size (required when objectSize=-1, recommend >= 10MB)
     * @return uploaded object URL
     */
    public String uploadObject(String bucketName, String objectKey, String contentType, InputStream inputStream,
            long objectSize, long partSize) {
        // Validate parameters
        if (bucketName == null || bucketName.trim().isEmpty()) {
            log.error("Bucket name cannot be null or empty");
            throw new BusinessException(ResponseEnum.S3_UPLOAD_ERROR);
        }
        if (objectKey == null || objectKey.trim().isEmpty()) {
            log.error("Object key cannot be null or empty");
            throw new BusinessException(ResponseEnum.S3_UPLOAD_ERROR);
        }
        if (inputStream == null) {
            log.error("Input stream cannot be null");
            throw new BusinessException(ResponseEnum.S3_UPLOAD_ERROR);
        }

        try {
            PutObjectArgs.Builder builder = PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectKey)
                    .stream(inputStream, objectSize, partSize);

            if (contentType != null && !contentType.isEmpty()) {
                builder.contentType(contentType);

View on GitHub (pinned to 5e758547a8)