apache/iceberg · error · UnsupportedOperationException

Identity transform is not supported

Error message

Identity transform is not supported

What it means

PartitionSpecVisitor provides default methods that throw UnsupportedOperationException so implementers only override the visit methods they care about. The legacy identity(sourceName, sourceId) default throws; visitors that don't override it but receive identity() dispatch will fail. Implement a visit method or use the fieldId-aware overload's default chain.

Source

Thrown at api/src/main/java/org/apache/iceberg/transforms/PartitionSpecVisitor.java:33

 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.iceberg.transforms;

import java.util.List;
import org.apache.iceberg.PartitionField;
import org.apache.iceberg.PartitionSpec;
import org.apache.iceberg.Schema;
import org.apache.iceberg.relocated.com.google.common.collect.Lists;

public interface PartitionSpecVisitor<T> {
  default T identity(int fieldId, String sourceName, int sourceId) {
    return identity(sourceName, sourceId);
  }

  default T identity(String sourceName, int sourceId) {
    throw new UnsupportedOperationException("Identity transform is not supported");
  }

  default T bucket(int fieldId, String sourceName, int sourceId, int numBuckets) {
    return bucket(sourceName, sourceId, numBuckets);
  }

  default T bucket(String sourceName, int sourceId, int numBuckets) {
    throw new UnsupportedOperationException("Bucket transform is not supported");
  }

  default T truncate(int fieldId, String sourceName, int sourceId, int width) {
    return truncate(sourceName, sourceId, width);
  }

  default T truncate(String sourceName, int sourceId, int width) {
    throw new UnsupportedOperationException("Truncate transform is not supported");
  }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Override identity(int fieldId, String sourceName, int sourceId) (or the 2-arg overload) in your visitor to return a value.
  2. If identity fields are unsupported in your target, throw a domain-specific error explicitly rather than relying on the default.
  3. Pre-scan the spec (PartitionSpecVisitor.visit(spec)) in tests to ensure every transform type your visitor lacks cannot occur.

Example fix

// before
new PartitionSpecVisitor<String>() {
  public String bucket(String name, int id, int n) { return ...; }
}
// after
new PartitionSpecVisitor<String>() {
  public String bucket(String name, int id, int n) { return ...; }
  @Override
  public String identity(int fieldId, String sourceName, int sourceId) {
    return sourceName; // handle identity fields
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

boolean hasIdentity = spec.fields().stream().anyMatch(f -> f.transform().isIdentity());

Try / catch

try { return PartitionSpecVisitor.visit(spec, visitor); } catch (UnsupportedOperationException e) { throw new IllegalArgumentException("Spec contains unhandled identity field: " + spec, e); }

Prevention

When it happens

Trigger: A PartitionSpecVisitor implementation that does not override identity(int fieldId, String sourceName, int sourceId) nor identity(String sourceName, int sourceId), visiting a partition spec containing an identity partition field.

Common situations: Writing custom spec visitors (e.g. for SQL partition-expression translation, Hive/Spark converters) and forgetting the identity case; specs with identity fields processed by visitors built only for transforms.

Understand the failure class

Background: "NotImplementedError: Subclasses should override this method" / "must be implemented" — abstract method errors explained — this error's family across 40 libraries.

Related errors


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