{"record":{"id":"43c7cab7b7abfdc1","repo":"apache/seatunnel","slug":"unsupported-pending-split-value-type-value-getcl","errorCode":null,"errorMessage":"Unsupported pending split value type ${value.getClass().getName()} for reader ${entry.getKey()}.","messagePattern":"Unsupported pending split value type (.+?) for reader (.+?)\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-cdc/connector-cdc-tidb/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/tidb/source/enumerator/TiDBSourceCheckpointState.java","lineNumber":81,"sourceCode":"\n    private static Map<Integer, List<TiDBSourceSplit>> normalizePendingSplit(\n            Map<Integer, ?> pendingSplit) {\n        Map<Integer, List<TiDBSourceSplit>> normalizedPendingSplit = new HashMap<>();\n        if (pendingSplit == null) {\n            return normalizedPendingSplit;\n        }\n        for (Map.Entry<Integer, ?> entry : pendingSplit.entrySet()) {\n            Object value = entry.getValue();\n            if (value instanceof TiDBSourceSplit) {\n                normalizedPendingSplit.put(\n                        entry.getKey(),\n                        new ArrayList<>(Collections.singletonList((TiDBSourceSplit) value)));\n            } else if (value instanceof List) {\n                normalizedPendingSplit.put(entry.getKey(), copyPendingSplits((List<?>) value));\n            } else if (value == null) {\n                normalizedPendingSplit.put(entry.getKey(), new ArrayList<>());\n            } else {\n                throw new IllegalArgumentException(\n                        String.format(\n                                \"Unsupported pending split value type %s for reader %s.\",\n                                value.getClass().getName(), entry.getKey()));\n            }\n        }\n        return normalizedPendingSplit;\n    }\n\n    private static List<TiDBSourceSplit> copyPendingSplits(List<?> pendingSplits) {\n        List<TiDBSourceSplit> copiedPendingSplits = new ArrayList<>();\n        for (Object pendingSplit : pendingSplits) {\n            if (!(pendingSplit instanceof TiDBSourceSplit)) {\n                throw new IllegalArgumentException(\n                        String.format(\n                                \"Unsupported pending split list value type %s.\",\n                                pendingSplit == null ? \"null\" : pendingSplit.getClass().getName()));\n            }\n            copiedPendingSplits.add((TiDBSourceSplit) pendingSplit);","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-cdc/connector-cdc-tidb/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/tidb/source/enumerator/TiDBSourceCheckpointState.java#L63-L99","documentation":"Thrown by TiDBSourceCheckpointState.normalizePendingSplit when a reader's pending-splits entry loaded from checkpoint state is neither a TiDBSourceSplit, a List, nor null. The checkpoint restore path expects a strictly typed structure and rejects any other stored value type.","triggerScenarios":"Restoring from a checkpoint/savepoint where the pendingSplits map contains an unexpected value type — e.g. a state format produced by a different connector version, or corrupted/manually edited state where the value is a String or other object.","commonSituations":"Upgrading or downgrading SeaTunnel between versions that changed the pending-splits state schema; resuming from an incompatible checkpoint file; state mutated by custom code.","solutions":["Discard the incompatible checkpoint/savepoint and restart the job from a fresh state","Use a checkpoint produced by the same connector version (match versions between save and restore)","Inspect the state file to find the offending reader key and its stored value type","Migrate the state by converting legacy split entries into TiDBSourceSplit lists before restore"],"exampleFix":"// before: checkpoint holds legacy String split descriptors\n\"pendingSplits\": {\"reader-0\": \"split-1,split-2\"}\n// after: state as list of TiDBSourceSplit objects\n\"pendingSplits\": {\"reader-0\": [{\"splitId\": \"split-1\", ...}, {\"splitId\": \"split-2\", ...}]}","handlingStrategy":"validation","validationCode":"// Validate pending split state shape before restore\nfor (Map.Entry<String, Object> e : pendingSplits.entrySet()) {\n    Object v = e.getValue();\n    if (!(v == null || v instanceof TiDBSourceSplit || v instanceof List)) {\n        throw new IllegalStateException(\"Bad pending split for reader \" + e.getKey());\n    }\n}","typeGuard":"boolean isRestorablePendingSplit(Object v) {\n    return v == null || v instanceof TiDBSourceSplit\n        || (v instanceof List<?> l && l.stream().allMatch(s -> s instanceof TiDBSourceSplit));\n}","tryCatchPattern":"try {\n    state = TiDBSourceCheckpointState.fromCheckpoint(rawState);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Unsupported pending split value type\")) {\n        LOG.error(\"Checkpoint written by incompatible version; restart without restore\");\n    }\n    throw e;\n}","preventionTips":["Use the same SeaTunnel/connector version for checkpoint and restore","Never hand-edit checkpoint state files","Test savepoint/restore compatibility when upgrading the connector"],"tags":["cdc","tidb","checkpoint","state-restore","type-mismatch"],"backgroundTag":"config-type-mismatch","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"}