{"record":{"id":"13c63b06482d52a7","repo":"apache/iceberg","slug":"unsupported-split-change-splitschange-getclass","errorCode":null,"errorMessage":"Unsupported split change: {splitsChange.getClass()}","messagePattern":"Unsupported split change: (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/source/reader/IcebergSourceSplitReader.java","lineNumber":109,"sourceCode":"    }\n\n    if (currentReader.hasNext()) {\n      // Because Iterator#next() doesn't support checked exception,\n      // we need to wrap and unwrap the checked IOException with UncheckedIOException\n      try {\n        return currentReader.next();\n      } catch (UncheckedIOException e) {\n        throw e.getCause();\n      }\n    } else {\n      return finishSplit();\n    }\n  }\n\n  @Override\n  public void handleSplitsChanges(SplitsChange<IcebergSourceSplit> splitsChange) {\n    if (!(splitsChange instanceof SplitsAddition)) {\n      throw new UnsupportedOperationException(\n          String.format(\"Unsupported split change: %s\", splitsChange.getClass()));\n    }\n\n    if (splitComparator != null) {\n      List<IcebergSourceSplit> newSplits = Lists.newArrayList(splitsChange.splits());\n      newSplits.sort(splitComparator);\n      LOG.info(\"Add {} splits to reader: {}\", newSplits.size(), newSplits);\n      splits.addAll(newSplits);\n    } else {\n      LOG.info(\"Add {} splits to reader\", splitsChange.splits().size());\n      splits.addAll(splitsChange.splits());\n    }\n    metrics.incrementAssignedSplits(splitsChange.splits().size());\n    metrics.incrementAssignedBytes(calculateBytes(splitsChange));\n  }\n\n  @Override\n  public void wakeUp() {","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/source/reader/IcebergSourceSplitReader.java#L91-L127","documentation":"IcebergSourceSplitReader.handleSplitsChanges only supports SplitsAddition; any other SplitsChange type (e.g. SplitsRemoval) is rejected with UnsupportedOperationException. The batch reader model never shrinks its assigned split set, so removal changes indicate an unsupported source-event flow.","triggerScenarios":"The SourceReaderContext/reader pipeline delivers a SplitsChange that is not a SplitsAddition to handleSplitsChanges — typically a removal generated by a different source implementation or by hybrid source hand-off logic.","commonSituations":"Mixing the v1 and v2 Flink source implementations; using IcebergSource inside frameworks (e.g. HybridSource, custom enumerator wrappers) that emit removals; upgrading Flink where the framework emits different split-change events.","solutions":["Ensure the enumerator used with IcebergSource only emits SplitsAddition (use the provided IcebergEnumerator, not a custom one emitting removals).","Check that you are not combining the legacy FlinkInputFormat source with the new Source API split changes.","If using HybridSource or hand-off, verify the hand-off contract produces additions only, or upgrade to a connector version supporting the change type.","Capture splitsChange.getClass() from the message to identify which framework component emitted the unsupported change."],"exampleFix":"// before: custom enumerator\nnew SplitEnumerator() { ... context.assignSplits(removal); ... }\n// after: use Iceberg's enumerator\nnew ContinuousIcebergEnumerator(context, splitPlanner, scanContext);","handlingStrategy":"type-guard","validationCode":"// guard before delegating split changes to the reader\nif (splitsChange != null && !(splitsChange instanceof SplitsAddition)) {\n  LOG.warn(\"Ignoring unsupported split change: {}\", splitsChange.getClass());\n  return;\n}","typeGuard":"boolean isAddition(SplitsChange<IcebergSourceSplit> c) {\n  return c instanceof SplitsAddition;\n}","tryCatchPattern":null,"preventionTips":["Only pair IcebergSource with its own enumerator or components known to emit SplitsAddition only.","Don't wire the legacy InputFormat source events into the new Source API reader.","Verify HybridSource/hand-off setups emit compatible change types."],"tags":["flink","source-reader","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}