apache/seatunnel · error · java.lang.IllegalArgumentException
splitId must not be null
Error message
splitId must not be null
What it means
ChangeEventRecords.forFinishedSplit is a factory that records a snapshot split as finished; its javadoc and @throws require a non-null splitId. Passing null is rejected immediately with IllegalArgumentException("splitId must not be null"), since a finished split without an id cannot be tracked or acked to the split enumerator.
Source
Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-base/src/main/java/org/apache/seatunnel/connectors/cdc/base/source/split/ChangeEventRecords.java:86
public Set<String> finishedSplits() {
return finishedSnapshotSplits;
}
public static ChangeEventRecords forRecords(
final String splitId, final Iterator<SourceRecords> recordsForSplit) {
return new ChangeEventRecords(splitId, recordsForSplit, Collections.emptySet());
}
/**
* Creates a {@link ChangeEventRecords} that only indicates a split is finished.
*
* @param splitId the ID of the finished split, must not be null
* @return a new {@link ChangeEventRecords} instance
* @throws IllegalArgumentException if splitId is null
*/
public static ChangeEventRecords forFinishedSplit(final String splitId) {
if (splitId == null) {
throw new IllegalArgumentException("splitId must not be null");
}
return new ChangeEventRecords(null, null, Collections.singleton(splitId));
}
}
View on GitHub (pinned to cf67b549a7)
Solutions
- Validate the split id before calling forFinishedSplit; throw early at the source of the null.
- Trace where the id comes from (usually the assigned SourceSplit's id()) and fix the null propagation.
- Check checkpoint state serialization if the null appears only after job restore.
- Use the non-null split id from the currently assigned split object instead of a cached variable.
Example fix
// before
String splitId = currentSplit == null ? null : currentSplit.splitId();
ChangeEventRecords.forFinishedSplit(splitId); // throws if null
// after
if (currentSplit != null && currentSplit.splitId() != null) {
ChangeEventRecords.forFinishedSplit(currentSplit.splitId());
} Defensive patterns
Strategy: validation
Validate before calling
if (splitId == null) {
throw new IllegalStateException("Cannot mark finished: split id is null");
}
ChangeEventRecords.forFinishedSplit(splitId); Try / catch
try {
ChangeEventRecords.forFinishedSplit(splitId);
} catch (IllegalArgumentException e) {
log.error("Null split id; check state restore path");
} Prevention
- Always derive splitId directly from the assigned SourceSplit object.
- Validate split-state fields right after checkpoint restore/deserialization.
- Null-check ids at boundaries between enumerator and reader.
When it happens
Trigger: Calling ChangeEventRecords.forFinishedSplit(null), typically when the caller derived the split id from a variable that was never assigned, or from a state object where the split id was lost during serialization/restore.
Common situations: Custom CDC source reader code passing an uninitialized split id; deserialization of split state after checkpoint restore producing a null id; copying example code where the id variable is filled later.
Related errors
- sourcePath is null
- ResultSet cannot be null
- RowType cannot be null
- Please invoke DeserializationSchema#deserialize(byte[], Coll
- Please invoke DeserializationSchema#deserialize(byte[], Coll
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/0489853f58e5480e.
Report an issue: GitHub.