{"record":{"id":"3bd227de7b908319","repo":"apache/iceberg","slug":"cannot-scan-table-using-ref-s-configured-for-inc","errorCode":null,"errorMessage":"Cannot scan table using ref %s: configured for incremental data in snapshots (%s, %s]","messagePattern":"Cannot scan table using ref (.+?): configured for incremental data in snapshots \\((.+?), (.+?)\\]","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/IncrementalDataTableScan.java","lineNumber":49,"sourceCode":"import org.apache.iceberg.util.SnapshotUtil;\n\nclass IncrementalDataTableScan extends DataTableScan {\n  IncrementalDataTableScan(Table table, Schema schema, TableScanContext context) {\n    super(table, schema, context.useSnapshotId(null));\n    validateSnapshotIds(table, context.fromSnapshotId(), context.toSnapshotId());\n  }\n\n  @Override\n  public TableScan asOfTime(long timestampMillis) {\n    throw new UnsupportedOperationException(\n        String.format(\n            \"Cannot scan table as of time %s: configured for incremental data in snapshots (%s, %s]\",\n            timestampMillis, context().fromSnapshotId(), context().toSnapshotId()));\n  }\n\n  @Override\n  public TableScan useRef(String ref) {\n    throw new UnsupportedOperationException(\n        String.format(\n            \"Cannot scan table using ref %s: configured for incremental data in snapshots (%s, %s]\",\n            ref, context().fromSnapshotId(), context().toSnapshotId()));\n  }\n\n  @Override\n  public TableScan useSnapshot(long scanSnapshotId) {\n    throw new UnsupportedOperationException(\n        String.format(\n            \"Cannot scan table using scan snapshot id %s: configured for incremental data in snapshots (%s, %s]\",\n            scanSnapshotId, context().fromSnapshotId(), context().toSnapshotId()));\n  }\n\n  @Override\n  public TableScan appendsBetween(long fromSnapshotId, long toSnapshotId) {\n    validateSnapshotIdsRefinement(fromSnapshotId, toSnapshotId);\n    return new IncrementalDataTableScan(\n        table(),","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/IncrementalDataTableScan.java#L31-L67","documentation":"An incremental scan is pinned to a snapshot range (fromSnapshotId, toSnapshotId); switching it to a named ref/branch would replace that range with a single snapshot, which the scan does not support. useRef therefore throws UnsupportedOperationException unconditionally, reporting the configured range.","triggerScenarios":"Calling table.incrementalScan(...).useRef(\"branch-name\") on an incremental scan result.","commonSituations":"Generic scan-option plumbing that always sets a ref (e.g. 'snapshot-id'/'branch' options applied uniformly); users migrating from branch-scoped snapshot scans to incremental scans who keep the useRef call.","solutions":["Remove the useRef call; select the snapshot range with fromSnapshot(long) and toSnapshot(long) instead.","To scan a branch incrementally, resolve its current snapshot ID (SnapshotUtil.currentSnapshotId or table.snapshot(ref).snapshotId()) and pass it as toSnapshotId.","Guard with (scan instanceof IncrementalDataTableScan) before applying ref-based configuration."],"exampleFix":"// before\nTableScan scan = table.incrementalScan(startId).useRef(\"audit\");\n// after\nlong endId = table.snapshot(\"audit\").snapshotId();\nTableScan scan = table.incrementalScan(startId, endId);","handlingStrategy":"type-guard","validationCode":"if (scan instanceof org.apache.iceberg.IncrementalDataTableScan) {\n  // use fromSnapshot/toSnapshot instead of useRef\n}","typeGuard":"boolean supportsRef(TableScan scan) {\n  return !(scan instanceof org.apache.iceberg.IncrementalDataTableScan);\n}","tryCatchPattern":"try {\n  scan.useRef(ref);\n} catch (UnsupportedOperationException e) {\n  long endId = table.snapshot(ref).snapshotId();\n  scan = table.incrementalScan(fromId, endId);\n}","preventionTips":["Branch selection for incremental scans means picking the branch's current snapshot as toSnapshotId.","Centralize scan option handling so ref/snapshot options skip incremental scans."],"tags":["incremental-scan","branch-ref","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"}