apache/iceberg · error · UnsupportedOperationException
${this.getClass().getName()} does not implement insert
Error message
${this.getClass().getName()} does not implement insert What it means
The position-delta writer's insert() entry point in this inner class is deliberately unsupported: inserts must go through the delegate with an explicit spec and partition projection, not this raw single-row API. Calling it fails fast naming the concrete class.
Source
Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/SparkPositionDeltaWrite.java:615
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)
Solutions
- Route inserts through the writer's spec-aware insert(row, spec, partitionProjection) path.
- Verify the Spark action/delta plan is producing matching insert operations for the configured write mode.
- If using MERGE, ensure write.merge/insert mode configuration matches the supported writer (e.g. copy-on-write for unsupported paths).
Defensive patterns
Strategy: validation
Validate before calling
// call the spec-aware insert, not the raw insert(InternalRow) boolean safeToCall = writerSupportsInsertWithSpec(writer); // route inserts via delegate otherwise
Try / catch
try { writer.insert(row); } catch (UnsupportedOperationException e) { delegateInsertWithSpec(writer, row); } Prevention
- Always use insert(row, spec, partitionProjection) for position-delta writers
- Keep MERGE insert operations routed through the standard SparkWrite path
- Avoid custom write code calling generic Writer APIs on delta writers
When it happens
Trigger: Spark's writer framework invoking insert(InternalRow) directly on the position-delta writer class instead of the delegated insert(row, spec, partition) path.
Common situations: MERGE WHEN NOT MATCHED THEN INSERT routed to the wrong writer method, or custom write paths calling the generic insert API on a position-delta writer.
Related errors
- ${this.getClass().getName()} does not implement update
- Update must be represented as delete and insert
- Cannot apply unknown table change: ${change}
- SparkCachedTableCatalog does not support altering tables
- SparkCachedTableCatalog does not support dropping tables
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/4ff89ea0a0731dc9.
Report an issue: GitHub.