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
- Inspect the upstream source/transform to find why empty rows are emitted and filter them there
- Add a Filter/SQL transform before the sink to drop null rows explicitly
- Check row deserialization in the source (e.g. CDC format parsing) for bugs producing empty rows
- 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
- Audit upstream transforms for null emissions
- Add a Filter transform to drop empty rows explicitly before the sink
- Track skipped-row counts in sink metrics
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
- All fields in row are null, skipping
- Column already exists in table . Skipping add column…
- Column already exists in table . Skipping change column…
- Column does not exist in table . Skipping drop column…
- Conflict key field ' ' value is null or not found in row
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)