{"record":{"id":"0489853f58e5480e","repo":"apache/seatunnel","slug":"splitid-must-not-be-null","errorCode":null,"errorMessage":"splitId must not be null","messagePattern":"splitId must not be null","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-cdc/connector-cdc-base/src/main/java/org/apache/seatunnel/connectors/cdc/base/source/split/ChangeEventRecords.java","lineNumber":86,"sourceCode":"    public Set<String> finishedSplits() {\n        return finishedSnapshotSplits;\n    }\n\n    public static ChangeEventRecords forRecords(\n            final String splitId, final Iterator<SourceRecords> recordsForSplit) {\n        return new ChangeEventRecords(splitId, recordsForSplit, Collections.emptySet());\n    }\n\n    /**\n     * Creates a {@link ChangeEventRecords} that only indicates a split is finished.\n     *\n     * @param splitId the ID of the finished split, must not be null\n     * @return a new {@link ChangeEventRecords} instance\n     * @throws IllegalArgumentException if splitId is null\n     */\n    public static ChangeEventRecords forFinishedSplit(final String splitId) {\n        if (splitId == null) {\n            throw new IllegalArgumentException(\"splitId must not be null\");\n        }\n        return new ChangeEventRecords(null, null, Collections.singleton(splitId));\n    }\n}\n","sourceCodeStart":68,"sourceCodeEnd":91,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-cdc/connector-cdc-base/src/main/java/org/apache/seatunnel/connectors/cdc/base/source/split/ChangeEventRecords.java#L68-L91","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nString splitId = currentSplit == null ? null : currentSplit.splitId();\nChangeEventRecords.forFinishedSplit(splitId); // throws if null\n// after\nif (currentSplit != null && currentSplit.splitId() != null) {\n    ChangeEventRecords.forFinishedSplit(currentSplit.splitId());\n}","handlingStrategy":"validation","validationCode":"if (splitId == null) {\n    throw new IllegalStateException(\"Cannot mark finished: split id is null\");\n}\nChangeEventRecords.forFinishedSplit(splitId);","typeGuard":null,"tryCatchPattern":"try {\n    ChangeEventRecords.forFinishedSplit(splitId);\n} catch (IllegalArgumentException e) {\n    log.error(\"Null split id; check state restore path\");\n}","preventionTips":["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."],"tags":["cdc","null-check","api-misuse","argument-validation"],"backgroundTag":"null-argument","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}