{"record":{"id":"9d58f1922af76019","repo":"apache/iceberg","slug":"unsupported-type-variant","errorCode":null,"errorMessage":"Unsupported type: variant","messagePattern":"Unsupported type: variant","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"api/src/main/java/org/apache/iceberg/types/TypeUtil.java","lineNumber":753,"sourceCode":"\n    public T list(Types.ListType list, T elementResult) {\n      return null;\n    }\n\n    public T map(Types.MapType map, T keyResult, T valueResult) {\n      return null;\n    }\n\n    /**\n     * @deprecated will be removed in 2.0.0; use {@link #variant(Types.VariantType)} instead.\n     */\n    @Deprecated\n    public T variant() {\n      return variant(Types.VariantType.get());\n    }\n\n    public T variant(Types.VariantType variant) {\n      throw new UnsupportedOperationException(\"Unsupported type: variant\");\n    }\n\n    public T primitive(Type.PrimitiveType primitive) {\n      return null;\n    }\n  }\n\n  public static <T> T visit(Schema schema, SchemaVisitor<T> visitor) {\n    return visitor.schema(schema, visit(schema.asStruct(), visitor));\n  }\n\n  public static <T> T visit(Type type, SchemaVisitor<T> visitor) {\n    switch (type.typeId()) {\n      case STRUCT:\n        Types.StructType struct = type.asNestedType().asStructType();\n        List<T> results = Lists.newArrayListWithExpectedSize(struct.fields().size());\n        for (Types.NestedField field : struct.fields()) {\n          visitor.beforeField(field);","sourceCodeStart":735,"sourceCodeEnd":771,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/api/src/main/java/org/apache/iceberg/types/TypeUtil.java#L735-L771","documentation":"This is the deprecated single-arg T variant() hook (deprecated SchemaVisitor in TypeUtil). Visitors that do not override variant(Types.VariantType) get the default implementation, which throws UnsupportedOperationException when the traversal encounters a VariantType node. It exists so old visitor subclasses fail loudly instead of silently mishandling variant columns.","triggerScenarios":"Running a custom (or older) TypeUtil.SchemaVisitor subclass that does not override variant(Types.VariantType) against a schema containing a variant column; calling the deprecated variant() hook directly.","commonSituations":"Custom projection/pruning/rewriting visitors written before the Variant type was introduced; upgrading Iceberg and pointing existing visitors at tables that now contain variant columns; libraries internally using SchemaVisitor on user schemas with variant fields.","solutions":["Override variant(Types.VariantType variant) in the visitor subclass to return an appropriate value.","Remove variant columns from the schema before visiting if variants are unsupported.","Migrate off the deprecated visitor hook to the non-deprecated variant(Types.VariantType) method.","Catch UnsupportedOperationException if variants are intentionally unsupported by the visitor."],"exampleFix":"// before\nclass MyVisitor extends TypeUtil.SchemaVisitor<String> {\n  // no variant() override -> throws on variant columns\n}\n// after\nclass MyVisitor extends TypeUtil.SchemaVisitor<String> {\n  @Override\n  public String variant(Types.VariantType variant) {\n    return Types.VariantType.get().toString();\n  }\n}","handlingStrategy":"try-catch","validationCode":"boolean hasVariant = schema.columns().stream().anyMatch(Types.NestedField::isVariant);\nif (hasVariant) { /* ensure visitor overrides variant() */ }","typeGuard":"boolean visitorHandlesVariants = MyVisitor.class\n    .getMethod(\"variant\", Types.VariantType.class).getDeclaringClass() != TypeUtil.SchemaVisitor.class;","tryCatchPattern":"try {\n  T result = TypeUtil.visit(schema, visitor);\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage().contains(\"variant\")) { /* strip variant columns or upgrade visitor */ }\n  throw e;\n}","preventionTips":["Always override variant(Types.VariantType) when subclassing visitors.","Detect variant columns before traversal and handle them explicitly.","Update legacy visitors when upgrading Iceberg past variant support."],"tags":["visitor","unsupported-operation","iceberg","variant"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}