{"record":{"id":"d07cf76de71edde5","repo":"apache/iceberg","slug":"this-getclass-getname-does-not-implement-up-d07cf7","errorCode":null,"errorMessage":"${this.getClass().getName()} does not implement update","messagePattern":"(.+?) does not implement update","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/source/SparkPositionDeltaWrite.java","lineNumber":647,"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":629,"sourceCodeEnd":665,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/source/SparkPositionDeltaWrite.java#L629-L665","documentation":"The position-delta writer variant that appends position deletes supports only write() of delete markers; Spark's RowDataWriter.update(metadata, id, row) contract for updating rows in place is not implemented and always throws UnsupportedOperationException. Updates to Iceberg tables must be expressed as a delete plus an insert.","triggerScenarios":"Spark's MERGE/UPDATE execution invoking update() on the FanoutPositionDelete writer produced by SparkPositionDeltaWrite — i.e. a delta write plan that asks the position-delete delegate to update rows in place.","commonSituations":"Running UPDATE/MERGE statements whose plans attempt copy-on-write-style row updates through a position-delta (merge-on-read) writer; custom Spark sinks calling the wrong write method.","solutions":["Ensure the Spark plan expresses updates as delete+insert (use Iceberg's standard UPDATE/MERGE support rather than calling update() on the writer)","Use a writer implementation that supports updates (e.g. V2 copy-on-write path) if in-place update semantics are required","Wrap the operation with Iceberg's procedures (CALL iceberg.system.merge/update) instead of custom writer code"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (plan.requiresInPlaceUpdate()) {\n  throw new IllegalArgumentException(\"Use delete+insert or copy-on-write path\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never call update() on position-delete delta writers","Use Iceberg's UPDATE/MERGE procedures which decompose updates correctly","Route row mutations to writers that advertise support for them"],"tags":["spark","merge-on-read","unsupported-operation"],"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"}