apache/iceberg · error · UnsupportedOperationException
Cannot update InternalRecordWrapper
Error message
Cannot update InternalRecordWrapper
What it means
InternalRecordWrapper is a read-only StructLike view over another record/wrapper. Its set(int pos, T value) mutator is intentionally unsupported because the wrapper delegates reads but never owns mutable storage. Attempting to write through the wrapper throws UnsupportedOperationException.
Source
Thrown at data/src/main/java/org/apache/iceberg/data/InternalRecordWrapper.java:112
}
@Override
public <T> T get(int pos, Class<T> javaClass) {
if (transforms[pos] != null) {
Object value = wrapped.get(pos, Object.class);
if (value == null) {
// transforms function don't allow to handle null values, so just return null here.
return null;
} else {
return javaClass.cast(transforms[pos].apply(value));
}
}
return wrapped.get(pos, javaClass);
}
@Override
public <T> void set(int pos, T value) {
throw new UnsupportedOperationException("Cannot update InternalRecordWrapper");
}
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Unwrap and mutate the underlying record instead of the wrapper (access the wrapped object).
- Build a new record with the desired values rather than writing through the wrapper.
- Use a mutable StructLike (e.g. Record from GenericRecord or InternalRecord) as the write target.
- Restructure code so wrappers are used only on the read/projection side.
Example fix
// before wrapper.set(2, newValue); // UnsupportedOperationException // after Record inner = (Record) Data.getDataFromType(wrapper.wrapped()); inner.set(2, newValue);
Defensive patterns
Strategy: type-guard
Validate before calling
if (structLike instanceof InternalRecordWrapper) {
throw new IllegalArgumentException("Wrapper is read-only; mutate the wrapped record instead");
} Type guard
StructLike writableTarget(StructLike s) {
return (s instanceof InternalRecordWrapper)
? ((InternalRecordWrapper) s).wrapped() instanceof StructLike
? (StructLike) ((InternalRecordWrapper) s).wrapped()
: null
: s;
} Try / catch
try {
struct.set(pos, value);
} catch (UnsupportedOperationException e) {
throw new IllegalStateException("Pass a mutable record, not an InternalRecordWrapper", e);
} Prevention
- Treat InternalRecordWrapper strictly as a read-only projection view.
- Only pass mutable records (e.g. GenericData.Record / InternalRecord) to write paths.
- Avoid reusing projection wrappers as output containers in generic StructLike code.
When it happens
Trigger: Calling set(pos, value) on an InternalRecordWrapper instance — e.g. code treating the wrapper as a writable StructLike when projecting, copying, or writing records through APIs that accept StructLike.
Common situations: Passing an InternalRecordWrapper to a writer or data-path that calls StructLike.set; reusing projection wrappers as output records; generic code that both reads and writes StructLike instances.
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
- Cannot set fields in a TypeProjection
- Not implemented: set
- Not implemented: set
- Not implemented: set
- Can't retrieve values from an empty struct
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/68869685b2e0bc51.
Report an issue: GitHub.