{"record":{"id":"b0bddfec30f0f1de","repo":"apache/seatunnel","slug":"no-split-assigned","errorCode":null,"errorMessage":"No split assigned","messagePattern":"No split assigned","errorType":"exception","errorClass":"java.lang.IllegalStateException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-cdc/connector-cdc-base/src/main/java/org/apache/seatunnel/connectors/cdc/base/source/reader/IncrementalSourceSplitReader.java","lineNumber":234,"sourceCode":"        }\n        if (splitId.equals(emittedFinishedSplitId)) {\n            return NoSplitRecords.INSTANCE;\n        }\n        emittedFinishedSplitId = splitId;\n        return ChangeEventRecords.forFinishedSplit(splitId);\n    }\n\n    private static final class NoSplitRecords implements RecordsWithSplitIds<SourceRecords> {\n        private static final NoSplitRecords INSTANCE = new NoSplitRecords();\n\n        @Override\n        public String nextSplit() {\n            return null;\n        }\n\n        @Override\n        public SourceRecords nextRecordFromSplit() {\n            throw new IllegalStateException(\"No split assigned\");\n        }\n\n        @Override\n        public Set<String> finishedSplits() {\n            return Collections.emptySet();\n        }\n    }\n}\n","sourceCodeStart":216,"sourceCodeEnd":243,"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/reader/IncrementalSourceSplitReader.java#L216-L243","documentation":"In the split-reader's empty-state inner class, nextRecordFromSplit() unconditionally throws IllegalStateException(\"No split assigned\"). This placeholder implementation exists for the state where the reader holds no split, so any request to emit a record in that state is an internal contract violation: the framework should never poll records without a split first being assigned via nextSplit().","triggerScenarios":"The source reader framework calls nextRecordFromSplit() while the active split-reader state has nextSplit() returning null (no assigned split), e.g. after all splits finished or before assignment.","commonSituations":"Engine asking for records from a reader that just finished its splits; a state-transition bug where the reader wasn't switched back to a records-holding state; custom CDC source code invoking the reader API out of order.","solutions":["Ensure hasNext()/nextRecordFromSplit() are only called after a non-null split is assigned; check the split-reader state machine in the connector.","Verify the enumerator actually assigns snapshot/incremental splits before the reader starts polling (check split assignment logs).","Upgrade connector-cdc-base; some versions fixed lifecycle ordering between split assignment and record polling.","If you wrote a custom SourceReader, guard nextRecordFromSplit to return null instead of throwing when no split is assigned."],"exampleFix":"// before\npublic SourceRecords nextRecordFromSplit() {\n    throw new IllegalStateException(\"No split assigned\");\n}\n// after\npublic SourceRecords nextRecordFromSplit() {\n    if (currentSplitId == null) {\n        return null; // signal no more records for now\n    }\n    return pollCurrentSplit();\n}","handlingStrategy":"type-guard","validationCode":"// poll only when a split is available\nif (reader.nextSplit() == null) { return; }","typeGuard":"boolean hasAssignedSplit = currentSplitId != null;\nif (!hasAssignedSplit) return null;","tryCatchPattern":"try {\n    record = reader.nextRecordFromSplit();\n} catch (IllegalStateException e) {\n    if (e.getMessage().equals(\"No split assigned\")) { /* wait for assignment */ }\n}","preventionTips":["Never invoke record polling before the enumerator assigns a split.","Stop polling once finishedSplits() covers the current split.","Follow upstream SourceReader lifecycle ordering when writing custom readers."],"tags":["cdc","source-reader","lifecycle","internal-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}