apache/seatunnel · warning

Received empty row data, skipping

Error message

Received empty row data, skipping

What it means

DatabendSinkWriter.write() skips rows that are null, have null fields array, or zero fields, logging this warning and returning without error. This guards the JDBC insert path against malformed upstream data that would otherwise cause a NullPointerException or an empty INSERT. The record is silently dropped from the sink output.

Solutions

  1. Inspect the upstream source/transform to find why empty rows are emitted and filter them there
  2. Add a Filter/SQL transform before the sink to drop null rows explicitly
  3. Check row deserialization in the source (e.g. CDC format parsing) for bugs producing empty rows
  4. If these rows should never exist, enable stricter validation upstream so the job fails fast and surfaces the producer

Example fix

// before
if (row == null || row.getFields() == null || row.getFields().length == 0) {
    log.warn("Received empty row data, skipping");
    return;
}
// after
if (row == null || row.getFields() == null || row.getFields().length == 0) {
    log.warn("Received empty row data, skipping. Upstream record: {}", row);
    emptyRowCounter.inc();
    return;
}
Defensive patterns

Strategy: validation

Validate before calling

// before sending to sink, validate rows upstream
if (row == null || row.getFields() == null || row.getFields().length == 0) {
    throw new IllegalArgumentException("Upstream produced empty SeaTunnelRow");
}

Type guard

boolean isWritable(SeaTunnelRow row) {
    return row != null && row.getFields() != null && row.getFields().length > 0;
}

Try / catch

// not applicable: warning is logged and row skipped; no exception propagates

Prevention

When it happens

Trigger: An upstream transform or source emits a null SeaTunnelRow, or a row constructed with new SeaTunnelRow(0) / null fields array reaches the Databend sink.

Common situations: Misconfigured source producing empty rows; transform (e.g. SQL/Filter) emitting nulls for filtered-out records; deserialization bugs producing empty field arrays.

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 apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/f6b0d4ec150cfd63. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-connectors-v2/connector-databend/src/main/java/org/apache/seatunnel/connectors/seatunnel/databend/sink/DatabendSinkWriter.java:337

                tableSchema.getColumns().stream()
                        .map(column -> "`" + column.getName() + "`")
                        .collect(Collectors.toList());

        String placeholders = String.join(", ", Collections.nCopies(columnNames.size(), "?"));

        return String.format(
                "INSERT INTO %s (%s) VALUES (%s)",
                tableName, String.join(", ", columnNames), placeholders);
    }

    @Override
    public void write(SeaTunnelRow row) {
        try {
            log.info("Writing row: {}", row);

            // check if row is null or empty
            if (row == null || row.getFields() == null || row.getFields().length == 0) {
                log.warn("Received empty row data, skipping");
                return;
            }

            if (isCdcMode) {
                processCdcRow(row);
            } else {
                processTraditionalRow(row);
            }

            batchCount++;
            log.info("Batch count after adding row: {}", batchCount);

            if (batchCount >= batchSize) {
                log.info("Batch size {} reached, executing batch", batchSize);
                executeBatch();
                log.info("Batch executed successfully");
            }
        } catch (Exception e) {

View on GitHub (pinned to cf67b549a7)