{"record":{"id":"1877363ec017c259","repo":"apache/iceberg","slug":"remove-is-not-supported-187736","errorCode":null,"errorMessage":"Remove is not supported","messagePattern":"Remove is not supported","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/DVIterator.java","lineNumber":104,"sourceCode":"          rowValues.add(ScanTaskUtil.contentSizeInBytes(deleteFile));\n        } else if (fieldId == MetadataColumns.DELETE_FILE_ROW_FIELD_ID) {\n          // DVs don't track the row that was deleted\n          rowValues.add(null);\n        }\n      }\n\n      this.row = new GenericInternalRow(rowValues.toArray());\n    } else if (null != deletedPositionIndex) {\n      // only update the deleted position if necessary, everything else stays the same\n      row.update(deletedPositionIndex, position);\n    }\n\n    return row;\n  }\n\n  @Override\n  public void remove() {\n    throw new UnsupportedOperationException(\"Remove is not supported\");\n  }\n\n  @Override\n  public void close() {}\n}\n","sourceCodeStart":86,"sourceCodeEnd":110,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/DVIterator.java#L86-L110","documentation":"DVIterator.remove implements the JDK Iterator contract but throws UnsupportedOperationException because the iterator is read-only. Deletion-vector iterators must never mutate the underlying data stream. Calling remove() is always a caller bug.","triggerScenarios":"Any code invoking iterator.remove() on the InternalRow iterator produced for a deletion-vector scan task — typically generic collection-consuming frameworks that call remove() to prune elements.","commonSituations":"Custom Spark readers/extensions iterating DV results with mutable Iterator usage; third-party code assuming all Iceberg iterators are mutable.","solutions":["Do not call remove(); iterate read-only and collect rows to keep into a new collection instead.","If deletion is intended, write a delete file / deletion vector via the Iceberg writer API instead of mutating scan output."],"exampleFix":"// before\nwhile (it.hasNext()) { Row r = it.next(); if (bad(r)) it.remove(); }\n// after\nList<Row> kept = new ArrayList<>();\nwhile (it.hasNext()) { Row r = it.next(); if (!bad(r)) kept.add(r); }","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"// do not call remove(); implement filtering instead\n// pattern: if (iter instanceof DVMutabilityCheck d && !d.isMutable()) collectInstead();","preventionTips":["Treat all Iceberg scan iterators as read-only.","Never invoke Iterator.remove() on scan results.","Model deletions via Iceberg delete files/rows API, not by mutating read output."],"tags":["spark","iterator","deletion-vector","read-only"],"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"}