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.

Solutions

  1. Unwrap and mutate the underlying record instead of the wrapper (access the wrapped object).
  2. Build a new record with the desired values rather than writing through the wrapper.
  3. Use a mutable StructLike (e.g. Record from GenericRecord or InternalRecord) as the write target.
  4. 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

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


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

Appendix: 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)