apache/iceberg · error · java.lang.UnsupportedOperationException
Not implemented: set
Error message
Not implemented: set
What it means
SparkStructLike adapts a Spark InternalRow to Iceberg's StructLike interface for reading; it is read-only by design. Calling set(pos, value) on it throws this UnsupportedOperationException because mutating Spark's internal rows through this wrapper is not implemented. StructLike mutation requires a mutable struct implementation.
Source
Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/SparkStructLike.java:52
public SparkStructLike wrap(Row row) {
this.wrapped = row;
return this;
}
@Override
public int size() {
return type.fields().size();
}
@Override
public <T> T get(int pos, Class<T> javaClass) {
Types.NestedField field = type.fields().get(pos);
return javaClass.cast(SparkValueConverter.convert(field.type(), wrapped.get(pos)));
}
@Override
public <T> void set(int pos, T value) {
throw new UnsupportedOperationException("Not implemented: set");
}
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Use a mutable StructLike implementation and copy values into it instead of setting on SparkStructLike
- Rewrite the code path to read values via get(pos, javaClass) rather than mutating
- Wrap with your own StructLike that holds a materialized Object[] you can set
- If writing data, construct Iceberg records directly instead of adapting Spark rows
Example fix
// before ((StructLike) sparkStructLike).set(0, "a"); // UnsupportedOperationException // after Object[] copy = new Object[structLike.size()]; for (int i = 0; i < copy.length; i++) copy[i] = structLike.get(i, Object.class); mutableStructLike.set(0, "a"); // mutable implementation
Defensive patterns
Strategy: type-guard
Validate before calling
// SparkStructLike is read-only; ensure your path never requires writes assert !isWritePath; // writers must use mutable StructLike implementations
Type guard
if (structLike instanceof org.apache.iceberg.spark.SparkStructLike) {
throw new IllegalStateException("SparkStructLike is read-only; copy to a mutable StructLike first");
} Try / catch
try {
structLike.set(pos, value);
} catch (UnsupportedOperationException e) {
// materialize into Object[]/mutable record and set there
} Prevention
- Treat SparkStructLike strictly as a read adapter
- Copy Spark rows into mutable StructLike implementations for write paths
- Check StructLike mutability requirements in generic utilities before reuse
- Add unit tests that fail fast if write paths receive read adapters
When it happens
Trigger: Calling ((StructLike) sparkStructLike).set(i, value); using a code path that expects a writable StructLike (e.g. writers, partition key builders that mutate) with a row obtained from Spark reader context.
Common situations: Custom Spark scan/read extensions trying to mutate rows in place; generic Iceberg utilities that accept StructLike for writes being handed a Spark row wrapper; test code assuming StructLike is always mutable.
Related errors
- Not implemented: set
- Cannot set fields in a TypeProjection
- Cannot update InternalRecordWrapper
- Not implemented: set
- Remove is not supported
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/57b3bb28291f65cd.
Report an issue: GitHub.