iflytek/astron-agent · error · BusinessException

RESPONSE_FAILED

RESPONSE_FAILED

Error message

Headers not yet validated, please check Excel file.

What it means

This error is thrown by the EasyExcel row listener DBExcelReadListener when a data row arrives through invoke() before invokeHeadMap() has successfully validated the sheet header. The listener sets headerValidated=true only after the header collection check passes, so this indicates the header callback never ran or never completed before rows were processed. It is an internal ordering invariant: headers must be validated before any row parsing.

Solutions

  1. Ensure the Excel file has a header row exactly matching the expected field names as its first row and read it with the default headRowNumber (do not set headRowNumber(0)).
  2. Download the provided import template and fill data starting from row 2.
  3. If reading programmatically, call the listener through EasyExcel.read so invokeHeadMap is triggered, and verify headers match the table field names (order-insensitive collection equality).

Example fix

// before
EasyExcel.read(file).headRowNumber(0).sheet().doRead(); // header skipped, rows hit invoke first
// after
EasyExcel.read(file).sheet().doRead(); // default headRowNumber=1, invokeHeadMap validates first
Defensive patterns

Strategy: validation

Validate before calling

// before reading, check the file's first row contains the expected headers
try (var wb = org.apache.poi.ss.usermodel.WorkbookFactory.create(inputStream)) {
    var row = wb.getSheetAt(0).getRow(0);
    if (row == null || row.getLastCellNum() < 1) {
        throw new IllegalArgumentException("Excel file is missing its header row");
    }
}

Try / catch

try {
    EasyExcel.read(file, listener).sheet().doRead();
} catch (BusinessException e) {
    // prompt user: re-add header row / use the official template
}

Prevention

When it happens

Trigger: Uploading an Excel file whose first sheet row is missing or empty so invokeHeadMap is not invoked before data rows; calling EasyExcel read with headRowNumber(0) or a custom read configuration that skips the header row; programmatically feeding rows to the listener without a header row.

Common situations: A user template file where the header row was deleted or the sheet starts at a different row; uploading a CSV-like file with no header; automated tests or scripts that construct workbooks without the header row.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/database/DBExcelReadListener.java:77

        notNullFieldsList = tableFields.stream()
                .filter(f -> !Arrays.asList(SYSTEM_FIELDS).contains(f.getName()))
                .filter(DbTableField::getIsRequired)
                .map(DbTableField::getName)
                .collect(Collectors.toList());

        // Here requires consistent order: maintain consistency with your original logic
        if (!CollectionUtils.isEqualCollection(expectedHeaders, actualHeaders)) {
            throw new IllegalArgumentException("Header mismatch! Expected headers: " + expectedHeaders + ", Actual headers: " + actualHeaders);
        } else {
            expectedHeaders = actualHeaders;
        }
        headerValidated = true;
    }

    @Override
    public void invoke(Map<Integer, String> row, AnalysisContext context) {
        if (!headerValidated) {
            throw new BusinessException(ResponseEnum.RESPONSE_FAILED, "Headers not yet validated, please check Excel file.");
        }
        if (accepted >= maxRows) {
            return; // Exceed limit, directly ignore subsequent rows to ensure availability
        }

        Map<String, Object> out = new LinkedHashMap<>();
        out.put("uid", uid);

        for (int i = 0; i < expectedHeaders.size(); i++) {
            String header = expectedHeaders.get(i);
            String raw = row.get(i); // Cell raw value (may be null)
            DbTableField meta = tableFields.stream()
                    .filter(f -> f.getName().equals(header))
                    .findFirst()
                    .orElseThrow(() -> new BusinessException(ResponseEnum.RESPONSE_FAILED, "Field " + header + " does not exist!"));

            Object v;
            if (StringUtils.isBlank(raw)) {

View on GitHub (pinned to 5e758547a8)