apache/iceberg · error · UnsupportedOperationException

Not implemented for variant

Error message

Not implemented for variant

What it means

The SparkTypeVisitor base exposes a variant() hook for Spark's VariantType, but the default implementation (and this dispatch layer) throws UnsupportedOperationException. Variants require explicit support in the concrete visitor; using a visitor that has not implemented it against a schema containing a VariantType column fails.

Source

Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/SparkTypeVisitor.java:64

          visit(((MapType) type).keyType(), visitor),
          visit(((MapType) type).valueType(), visitor));

    } else if (type instanceof ArrayType) {
      return visitor.array((ArrayType) type, visit(((ArrayType) type).elementType(), visitor));

    } else if (type instanceof VariantType) {
      return visitor.variant((VariantType) type);

    } else if (type instanceof UserDefinedType) {
      throw new UnsupportedOperationException("User-defined types are not supported");

    } else {
      return visitor.atomic(type);
    }
  }

  public T variant(VariantType variant) {
    throw new UnsupportedOperationException("Not implemented for variant");
  }

  public T struct(StructType struct, List<T> fieldResults) {
    return null;
  }

  public T field(StructField field, T typeResult) {
    return null;
  }

  public T array(ArrayType array, T elementResult) {
    return null;
  }

  public T map(MapType map, T keyResult, T valueResult) {
    return null;
  }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Avoid variant columns on this code path — cast them to string/JSON-typed columns instead
  2. Implement variant() in your concrete SparkTypeVisitor subclass to handle VariantType explicitly
  3. Upgrade iceberg-spark to a release where the caller's visitor supports variant types

Example fix

// before
class MyVisitor extends SparkTypeVisitor<String> {} // variant() throws
// after
class MyVisitor extends SparkTypeVisitor<String> {
  @Override public String variant(VariantType variant) { return "variant"; }
}
Defensive patterns

Strategy: validation

Validate before calling

boolean hasVariant = java.util.Arrays.stream(schema.fields()).anyMatch(f -> f.dataType() instanceof VariantType);
if (hasVariant && !visitorSupportsVariant) throw new IllegalArgumentException("Variant column present but visitor lacks variant() support");

Type guard

boolean isVariant(DataType t) { return t instanceof VariantType; }

Try / catch

try { visit(schema, visitor); } catch (UnsupportedOperationException e) { if (e.getMessage().contains("Not implemented for variant")) { /* cast variant to string or implement variant() */ } throw e; }

Prevention

When it happens

Trigger: Calling SparkTypeVisitor.visit on a schema that contains a VariantType (Spark semi-structured JSON type) while the concrete visitor does not override variant().

Common situations: Schemas from Spark 4.x semi-structured sources (e.g. JSON ingestion as variant); generic schema-inspection tooling hitting Iceberg/Spark versions where variant is not supported on this code path.

Related errors


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