apache/iceberg · error · UnsupportedOperationException

Not implemented: set

Error message

Not implemented: set

What it means

SparkStructLike is a read-only wrapper that adapts an Iceberg StructLike row into Spark internal (Catalyst) values; get() converts values for reading, but mutation is intentionally unimplemented. Calling set(pos, value) always throws UnsupportedOperationException because rows produced for scanning are immutable views, not writable buffers.

Solutions

  1. Do not mutate SparkStructLike; build a new record/Row with the changed value instead.
  2. Use a mutable StructLike implementation (e.g. GenericsHelpers record) as the write target, then wrap it read-only with SparkStructLike for conversion.
  3. If writing Spark rows, use the Spark writer APIs (SparkWrite) rather than mutating scan-produced structs.

Example fix

// before
sparkStructLike.set(pos, newValue); // throws UnsupportedOperationException
// after
GenericData.Record record = new GenericData.Record(sparkStructLike.structType());
for (int i = 0; i < record.size(); i++) record.set(i, sparkStructLike.get(i, Object.class));
record.set(pos, newValue);
Defensive patterns

Strategy: type-guard

Validate before calling

// treat SparkStructLike strictly as read-only in your code; never pass it where a mutable StructLike is required
if (structLike instanceof SparkStructLike) { /* read-only: do not call set */ }

Type guard

boolean isWritable = !(structLike instanceof SparkStructLike);

Try / catch

try {
  structLike.set(pos, value);
} catch (UnsupportedOperationException e) {
  if ("Not implemented: set".equals(e.getMessage())) { /* copy record and mutate the copy */ }
  else throw e;
}

Prevention

When it happens

Trigger: Any code path calling SparkStructLike.set(pos, value) — e.g. writing into the wrapped struct during upserts, merges, or generic code assuming a mutable StructLike.

Common situations: Custom merge/upsert logic that mutates rows in place; test harnesses reusing a StructLike instance as an accumulator; generic Iceberg code that writes to StructLike passed a Spark-backed wrapper.

Related errors


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

Appendix: source

Thrown at spark/v3.5/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)