{"record":{"id":"1bcb766a894c97c5","repo":"apache/iceberg","slug":"this-getclass-getname-does-not-implement-up-1bcb76","errorCode":null,"errorMessage":"this.getClass().getName() +  does not implement update","messagePattern":"this\\.getClass\\(\\)\\.getName\\(\\) \\+  does not implement update","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/SparkPositionDeltaWrite.java","lineNumber":644,"sourceCode":"\n    @Override\n    public void delete(InternalRow metadata, InternalRow id) throws IOException {\n      int specId = metadata.getInt(specIdOrdinal);\n      PartitionSpec spec = specs.get(specId);\n\n      InternalRow partition = metadata.getStruct(partitionOrdinal, partitionRowWrapper.size());\n      StructProjection partitionProjection = partitionProjections.get(specId);\n      partitionProjection.wrap(partitionRowWrapper.wrap(partition));\n\n      String file = id.getString(fileOrdinal);\n      long position = id.getLong(positionOrdinal);\n      positionDelete.set(file, position);\n      delegate.write(positionDelete, spec, partitionProjection);\n    }\n\n    @Override\n    public void update(InternalRow metadata, InternalRow id, InternalRow row) {\n      throw new UnsupportedOperationException(\n          this.getClass().getName() + \" does not implement update\");\n    }\n\n    @Override\n    public void insert(InternalRow row) throws IOException {\n      throw new UnsupportedOperationException(\n          this.getClass().getName() + \" does not implement insert\");\n    }\n\n    @Override\n    public WriterCommitMessage commit() throws IOException {\n      close();\n\n      DeleteWriteResult result = delegate.result();\n      return new DeltaTaskCommit(result);\n    }\n\n    @Override","sourceCodeStart":626,"sourceCodeEnd":662,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/SparkPositionDeltaWrite.java#L626-L662","documentation":"The copy-on-write position-delete writer for MERGE/Delta operations only supports writing whole-row deletes identified by file and position. It deliberately throws UnsupportedOperationException from update() because updating a row in place is not representable — Spark Delta semantics require updates to be decomposed into delete+insert before reaching this writer.","triggerScenarios":"A Spark DELETE/MERGE ... UPDATE execution path calls update(metadata, id, row) on the SparkPositionDeltaWrite copy-on-write writer — only possible if a newer Spark Delta API surface routes an update op directly to this writer instead of split delete+insert.","commonSituations":"Custom or forked Spark integrations invoking the row-level writer API directly; running against a Spark version whose Delta execution calls update() rather than delete(); misuse of the internal writer API in tests/tools.","solutions":["Ensure updates are decomposed by Spark into delete+insert (use supported Spark/Iceberg version pairs for the v4.0 module).","Do not call update() directly on this writer; use delete() followed by insert()/reinsert().","If extending the writer, implement update() in your subclass instead of relying on the default.","Check that the command is routed through SparkRowLevelOperationBuilder, which produces the correct operation for the mode."],"exampleFix":"// before: direct update call on the writer\nwriter.update(metadataRow, idRow, updatedRow);\n// after: express as delete + insert\nwriter.delete(metadataRow, idRow);\nwriter.insert(updatedRow);","handlingStrategy":"type-guard","validationCode":"if (writer instanceof SparkPositionDeltaWrite && supportsUpdate(writer)) {\n  writer.update(meta, id, row);\n} else {\n  writer.delete(meta, id, row);\n  writer.insert(row);\n}","typeGuard":"boolean supportsInPlaceUpdate(Object w) { return w instanceof SupportsUpdate; }","tryCatchPattern":"try { writer.update(meta, id, row); } catch (UnsupportedOperationException e) {\n  writer.delete(meta, id, row); writer.insert(row);\n}","preventionTips":["Never call update() directly on Iceberg row-level writers; always decompose into delete+insert","Use supported Spark/Iceberg version pairs","Route writes through SparkRowLevelOperationBuilder, not writer internals"],"tags":["spark","merge-on-read","copy-on-write","row-level-operations"],"backgroundTag":"method-not-implemented","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"}