apache/seatunnel · error · IllegalArgumentException
event payload must not be null
Error message
event payload must not be null
What it means
SqliteWalStore.append() requires each EdgeEvent to carry a non-null payload byte array, since the payload is what is persisted into the WAL table. A null payload cannot be meaningfully appended and would break replay, so append() throws this IllegalArgumentException before starting the transaction.
Solutions
- Ensure the payload is set — pass an empty byte[0] instead of null for empty events before calling append().
- Fix the upstream serializer/codec so it emits empty arrays rather than null payloads.
- Validate event.getPayload() != null at the producer boundary before appending.
- Check where the EdgeEvent was constructed; a missing payload usually indicates a skipped assignment.
Example fix
// before byte[] payload = decode(body); // may return null store.append(new EdgeEvent(type, payload)); // after byte[] payload = decode(body); store.append(new EdgeEvent(type, payload == null ? new byte[0] : payload));
Defensive patterns
Strategy: type-guard
Validate before calling
if (event.getPayload() == null) { event = event.withPayload(new byte[0]); } Type guard
boolean hasPayload(EdgeEvent e) { return e.getPayload() != null; } Try / catch
try { store.append(event); } catch (IllegalArgumentException e) { if (e.getMessage().contains("payload must not be null")) { store.append(event.withPayload(new byte[0])); } else { throw e; } } Prevention
- Coerce empty messages to byte[0] at the serializer boundary.
- Never construct EdgeEvent without explicitly setting payload.
- Add producer-side assertions for payload != null in tests.
- Review codecs that may return null for empty input.
When it happens
Trigger: Calling walStore.append(event) with an EdgeEvent whose getPayload() returns null — e.g. an event constructed without payload bytes, or an upstream serializer that produced null for an empty message.
Common situations: Producers forwarding deserialized messages where empty bodies became null; building EdgeEvent objects by hand and forgetting setPayload; a codec that returns null instead of byte[0] for empty content.
Related errors
- AmazonDocumentDB option '' must be a valid BSON/JSON…
- AmazonDocumentDB option '' must not be blank
- API-01
- At least one sink plugin must be configured.
- At least one source plugin must be configured.
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/0fee712ab55a28c3.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-edge-agent/seatunnel-edge-agent-starter/src/main/java/org/apache/seatunnel/edge/agent/starter/wal/sqlite/SqliteWalStore.java:72
this.sourcePositionStore = new SqliteSourcePositionStore(connection, false);
}
public SqliteWalStore(Connection connection, boolean closeConnection) {
this.connection = Objects.requireNonNull(connection, "connection");
this.closeConnection = closeConnection;
this.sourcePositionStore = new SqliteSourcePositionStore(connection, false);
}
@Override
public EdgeSourcePositionStore sourcePositionStore() {
return sourcePositionStore;
}
@Override
public long append(EdgeEvent event) throws Exception {
byte[] payload = event.getPayload();
if (payload == null) {
throw new IllegalArgumentException("event payload must not be null");
}
long now = System.currentTimeMillis();
boolean autoCommit = connection.getAutoCommit();
connection.setAutoCommit(false);
try {
long batchId = SqliteBatchIdAllocator.allocateNext(connection);
try (PreparedStatement statement =
connection.prepareStatement(
WalSqlStatements.INSERT, Statement.RETURN_GENERATED_KEYS)) {
statement.setString(1, event.getSourceId());
statement.setBytes(2, payload);
statement.setLong(3, event.getEventTime());
statement.setBytes(4, MetadataSerde.serialize(event.getMetadata()));
statement.setString(5, WalRecordStatus.PENDING.name());
statement.setInt(6, 0);
statement.setLong(7, now);
statement.setLong(8, now);
statement.setLong(9, batchId);View on GitHub (pinned to cf67b549a7)