{"record":{"id":"9fa34e1ecc05ebdb","repo":"apache/iceberg","slug":"not-implemented-for-variant-9fa34e","errorCode":null,"errorMessage":"Not implemented for variant","messagePattern":"Not implemented for variant","errorType":"exception","errorClass":"java.lang.UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/SparkTypeVisitor.java","lineNumber":64,"sourceCode":"          visit(((MapType) type).keyType(), visitor),\n          visit(((MapType) type).valueType(), visitor));\n\n    } else if (type instanceof ArrayType) {\n      return visitor.array((ArrayType) type, visit(((ArrayType) type).elementType(), visitor));\n\n    } else if (type instanceof VariantType) {\n      return visitor.variant((VariantType) type);\n\n    } else if (type instanceof UserDefinedType) {\n      throw new UnsupportedOperationException(\"User-defined types are not supported\");\n\n    } else {\n      return visitor.atomic(type);\n    }\n  }\n\n  public T variant(VariantType variant) {\n    throw new UnsupportedOperationException(\"Not implemented for variant\");\n  }\n\n  public T struct(StructType struct, List<T> fieldResults) {\n    return null;\n  }\n\n  public T field(StructField field, T typeResult) {\n    return null;\n  }\n\n  public T array(ArrayType array, T elementResult) {\n    return null;\n  }\n\n  public T map(MapType map, T keyResult, T valueResult) {\n    return null;\n  }\n","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/SparkTypeVisitor.java#L46-L82","documentation":"The SparkTypeToIcebergType visitor's default variant() hook has no implementation; any concrete visitor that does not override it will throw when the schema contains a Spark VariantType column. This is an extension-point guard: subclass visitors must handle variant or reject it explicitly.","triggerScenarios":"A custom TypeVisitor subclass (extending SparkTypeVisitor) is applied to a Spark schema containing a VariantType column (Spark 4.x variant type) and the subclass does not override variant(VariantType).","commonSituations":"Upgrading to Spark 4.x where variant columns appear in schemas read from Parquet or defined via VARIANT literal; authors of custom type visitors forgetting to implement the new variant callback.","solutions":["Override variant(VariantType variant) in your visitor subclass and return the desired mapping (e.g. Types.VariantType.get())","Reject variant columns earlier by filtering them out of the schema before applying the visitor","Do not use the default visitor directly; subclass it and handle all relevant types"],"exampleFix":"// before\nclass MyVisitor extends SparkTypeVisitor<Type> { }\n// after\nclass MyVisitor extends SparkTypeVisitor<Type> {\n  @Override\n  public Type variant(VariantType variant) {\n    return Types.VariantType.get();\n  }\n}","handlingStrategy":"type-guard","validationCode":"// before applying visitor\nboolean hasVariant = false;\nfor (StructField f : sparkSchema.fields()) {\n  if (f.dataType().typeName().equalsIgnoreCase(\"variant\")) { hasVariant = true; break; }\n}\nif (hasVariant) throw new IllegalArgumentException(\"Variant columns require a visitor that implements variant()\");","typeGuard":"static boolean hasVariantColumn(StructType schema) {\n  for (StructField f : schema.fields()) {\n    if (f.dataType() instanceof org.apache.spark.sql.types.VariantType) return true;\n  }\n  return false;\n}","tryCatchPattern":"try { visitor.apply(type) } catch (UnsupportedOperationException e) { if (e.getMessage().contains(\"Not implemented for variant\")) { /* fallback: drop/reject variant columns */ } else throw e; }","preventionTips":["Always override variant() in SparkTypeVisitor subclasses","Check Spark 4.x variant columns early in schema validation"],"tags":["spark","variant","visitor","not-implemented"],"backgroundTag":"method-not-implemented","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"}