apache/iceberg · error · UnsupportedOperationException
Not implemented: set
Error message
Not implemented: set
What it means
SparkStructLike wraps a Spark InternalRow to expose it as Iceberg's StructLike. Iceberg's StructLike contract includes a set() mutation method, but this wrapper is read-only, so calling set() throws UnsupportedOperationException. It exists only to read struct values out of Spark rows during scans.
Source
Thrown at spark/v4.1/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
- Do not mutate SparkStructLike; treat it as read-only and build a mutable StructLike (e.g. via a Record or a fixed StructLike implementation) when writes are needed
- Copy the values out of the Spark row into your own mutable record before mutation
- Check whether the API you are calling truly needs a mutable StructLike; read paths (comparators, readers) never call set()
Example fix
// before
structLike.set(0, newValue); // throws UnsupportedOperationException
// after
Record copy = GenericRecord.create(schema).copyFieldValues(...);
copy.setField("col", newValue); Defensive patterns
Strategy: validation
Validate before calling
if (structLike instanceof SparkStructLike) {
throw new IllegalArgumentException("SparkStructLike is read-only; use a mutable record");
} Type guard
boolean isReadOnlyStructLike(StructLike s) { return s instanceof SparkStructLike; } Try / catch
try { s.set(pos, value); } catch (UnsupportedOperationException e) { /* build a mutable copy instead */ } Prevention
- Treat SparkStructLike as read-only; never pass it to write/update APIs
- Materialize values into GenericRecord or another mutable StructLike when mutation is required
- Check the receiving API's docs for whether it mutates its StructLike argument
When it happens
Trigger: Calling set(int pos, T value) on a SparkStructLike instance — e.g. passing it to code that assumes a mutable StructLike (such as writers or updaters) instead of read-only scan contexts.
Common situations: Piping an Iceberg-wrapped Spark row into a custom writer, updater, or copy routine that mutates StructLike fields; using SparkStructLike outside the read path it was designed for.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
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/4221589f4f4a1947.
Report an issue: GitHub.