apache/iceberg · error · UnsupportedOperationException

this.getClass().getName() + does not implement insert

Error message

this.getClass().getName() +  does not implement insert

What it means

This position-delete writer in SparkPositionDeltaWrite does not implement insert() — row insertion is handled by the paired data writer or via reinsert() in MoR variants. Calling insert() on this specific writer deliberately throws UnsupportedOperationException.

Solutions

  1. Route inserted rows to the data writer (SparkWrite) rather than the position-delete writer.
  2. Use the MoR writer's reinsert()/insert() path when operating in merge-on-read mode.
  3. Upgrade Spark/Iceberg versions so the Delta execution plan routes inserts to the correct writer.
  4. If implementing a custom writer, override insert() with real logic.

Example fix

// before: insert on delete writer
positionDeleteWriter.insert(row);
// after: delegate to the data writer
dataWriter.write(row);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(writer instanceof RowDataWriter)) { throw new IllegalArgumentException("Route inserts to the data writer"); }

Type guard

boolean acceptsInsert(Object w) { return w instanceof IcebergWriter && !(w instanceof PositionDeleteWriter); }

Try / catch

try { writer.insert(row); } catch (UnsupportedOperationException e) {
  dataWriter.write(row); // route to the data writer
}

Prevention

When it happens

Trigger: Code calls insert(row) on the copy-on-write position-delete writer of SparkPositionDeltaWrite instead of routing new rows to the data writer or the MoR writer's reinsert path.

Common situations: Custom Delta integrations or refactors that funnel both deletes and inserts through the delete writer; internal API misuse when writing MERGE results manually.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/4463067fd57e2776. Report an issue: GitHub.

Appendix: source

Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/SparkPositionDeltaWrite.java:650

      InternalRow partition = metadata.getStruct(partitionOrdinal, partitionRowWrapper.size());
      StructProjection partitionProjection = partitionProjections.get(specId);
      partitionProjection.wrap(partitionRowWrapper.wrap(partition));

      String file = id.getString(fileOrdinal);
      long position = id.getLong(positionOrdinal);
      positionDelete.set(file, position);
      delegate.write(positionDelete, spec, partitionProjection);
    }

    @Override
    public void update(InternalRow metadata, InternalRow id, InternalRow row) {
      throw new UnsupportedOperationException(
          this.getClass().getName() + " does not implement update");
    }

    @Override
    public void insert(InternalRow row) throws IOException {
      throw new UnsupportedOperationException(
          this.getClass().getName() + " does not implement insert");
    }

    @Override
    public WriterCommitMessage commit() throws IOException {
      close();

      DeleteWriteResult result = delegate.result();
      return new DeltaTaskCommit(result);
    }

    @Override
    public void abort() throws IOException {
      close();

      DeleteWriteResult result = delegate.result();
      SparkCleanupUtil.deleteTaskFiles(io, result.deleteFiles());
    }

View on GitHub (pinned to 86d9c8fc54)