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

  1. Use a mutable StructLike implementation and copy values into it instead of setting on SparkStructLike
  2. Rewrite the code path to read values via get(pos, javaClass) rather than mutating
  3. Wrap with your own StructLike that holds a materialized Object[] you can set
  4. 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

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


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