iflytek/astron-agent · error · BusinessException

INTERNAL_SERVER_ERROR

INTERNAL_SERVER_ERROR

Error message

BusinessException(ResponseEnum.INTERNAL_SERVER_ERROR)

What it means

SkillFileService.readFileFromS3 wraps S3 download/IO failures in a generic INTERNAL_SERVER_ERROR BusinessException. It means the skill file object could not be read from object storage (S3/MinIO) or the stream could not be read as bytes. The service deliberately hides the underlying IOException behind the platform's generic 500 code.

Solutions

  1. Verify MinIO/S3 is up and reachable from the toolkit service (docker compose ps, check the storage endpoint config).
  2. Check that the object exists at the stored objectKey in the configured bucket (aws s3 ls / mc ls).
  3. Validate s3 access-key/secret/bucket settings in the toolkit service configuration.
  4. Check the log for the suppressed IOException near this BusinessException to see the real cause.
  5. Re-upload the skill file to recreate a valid object record.

Example fix

// before
catch (IOException ex) {
    throw new BusinessException(ResponseEnum.INTERNAL_SERVER_ERROR);
}
// after
catch (IOException ex) {
    log.error("Failed to read skill file from S3, key={}", file.getObjectKey(), ex);
    throw new BusinessException(ResponseEnum.INTERNAL_SERVER_ERROR);
}
Defensive patterns

Strategy: try-catch

Validate before calling

boolean objectReachable = s3Util.doesObjectExist(bucket, file.getObjectKey());
if (!objectReachable) throw new IllegalStateException("Skill file object missing: " + file.getObjectKey());

Try / catch

try {
    String content = readSkillFile(record);
} catch (BusinessException e) {
    if ("INTERNAL_SERVER_ERROR".equals(e.getCode())) {
        log.warn("Skill file read failed; check S3 availability/config", e);
    }
}

Prevention

When it happens

Trigger: Calling the skill file read API whose file record points at S3: s3Util.getObject(file.getObjectKey()) throws IOException (object missing, wrong bucket/key, storage down, credentials invalid) or input.readAllBytes() fails mid-stream.

Common situations: MinIO/S3 not running or unreachable in the deployment; object key in the skill_file row is stale after a bucket migration or manual deletion; wrong S3 credentials/bucket config in application.yml; network timeout between toolkit service and storage.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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

Appendix: source

Thrown at console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/skill/SkillFileService.java:803

    }

    private String safeSegment(String value) {
        return StringUtils.defaultString(value)
                .replaceAll("[^a-zA-Z0-9._-]", "-")
                .replaceAll("-{2,}", "-");
    }

    private String readContent(SkillFile file) {
        if (StringUtils.isBlank(file.getObjectKey())) {
            return "";
        }
        try (InputStream input = s3Util.getObject(file.getObjectKey())) {
            if (input == null) {
                return "";
            }
            return new String(input.readAllBytes(), StandardCharsets.UTF_8);
        } catch (IOException ex) {
            throw new BusinessException(ResponseEnum.INTERNAL_SERVER_ERROR);
        }
    }

    private String readMultipartContent(MultipartFile file) {
        try {
            return new String(file.getBytes(), StandardCharsets.UTF_8);
        } catch (IOException e) {
            throw new BusinessException(ResponseEnum.INTERNAL_SERVER_ERROR);
        }
    }

    private boolean isSkillFile(String name) {
        return StringUtils.equalsIgnoreCase(name, SKILL_FILE_NAME);
    }

    private SkillMetadata extractSkillMetadata(String content, String fallbackName) {
        String name = null;
        String description = null;

View on GitHub (pinned to 5e758547a8)