apache/iceberg · error · UnsupportedOperationException

Can't modify an empty struct

Error message

Can't modify an empty struct

What it means

EmptyStructLike represents a zero-field struct (unpartitioned data). set() always throws because there is no field to write; mutating it indicates the caller is treating the shared empty placeholder as a writable record.

Source

Thrown at api/src/main/java/org/apache/iceberg/EmptyStructLike.java:45

  private EmptyStructLike() {}

  static EmptyStructLike get() {
    return INSTANCE;
  }

  @Override
  public int size() {
    return 0;
  }

  @Override
  public <T> T get(int pos, Class<T> javaClass) {
    throw new UnsupportedOperationException("Can't retrieve values from an empty struct");
  }

  @Override
  public <T> void set(int pos, T value) {
    throw new UnsupportedOperationException("Can't modify an empty struct");
  }

  @Override
  public boolean equals(Object other) {
    if (this == other) {
      return true;
    }

    return other != null && getClass() == other.getClass();
  }

  @Override
  public int hashCode() {
    return 0;
  }

  @Override
  public String toString() {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Guard the write path: if partitionType().fields().isEmpty(), skip the set loop
  2. Use a real writable StructLike (e.g. a Record or wrapper) sized to the partition type when fields exist
  3. Never write into the shared EmptyStructLike instance; it is a read-only singleton by design

Example fix

// before
for (int i = 0; i < fields.size(); i++) {
  struct.set(i, values.get(i));
}
// after
if (!(struct instanceof EmptyStructLike)) {
  for (int i = 0; i < fields.size(); i++) {
    struct.set(i, values.get(i));
  }
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (struct instanceof EmptyStructLike) { return; }

Type guard

boolean isWritable(StructLike s) {
  return !(s instanceof EmptyStructLike);
}

Try / catch

try {
  struct.set(pos, value);
} catch (UnsupportedOperationException e) {
  // ignore: unpartitioned empty struct has nothing to write
}

Prevention

When it happens

Trigger: Calling set(pos, value) on EmptyStructLike, e.g. when copying partition values into a StructLike buffer for a table with an empty partition spec, or writer code that unconditionally writes all projected positions.

Common situations: Custom appender/writer code that copies projected fields into a partition StructLike without checking whether the spec is unpartitioned; refactoring that replaced a real StructLike with the empty placeholder.

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/de8df939d7305cd4. Report an issue: GitHub.