{"record":{"id":"abc5cd1f207c4d72","repo":"apache/iceberg","slug":"variants-must-be-read-using-read-variantmetadata","errorCode":null,"errorMessage":"Variants must be read using read(VariantMetadata)","messagePattern":"Variants must be read using read\\(VariantMetadata\\)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"parquet/src/main/java/org/apache/iceberg/parquet/ParquetVariantReaders.java","lineNumber":49,"sourceCode":"import org.apache.iceberg.relocated.com.google.common.collect.Iterables;\nimport org.apache.iceberg.variants.PhysicalType;\nimport org.apache.iceberg.variants.ShreddedObject;\nimport org.apache.iceberg.variants.ValueArray;\nimport org.apache.iceberg.variants.Variant;\nimport org.apache.iceberg.variants.VariantMetadata;\nimport org.apache.iceberg.variants.VariantObject;\nimport org.apache.iceberg.variants.VariantValue;\nimport org.apache.iceberg.variants.Variants;\nimport org.apache.parquet.column.ColumnDescriptor;\nimport org.apache.parquet.column.page.PageReadStore;\n\npublic class ParquetVariantReaders {\n  private ParquetVariantReaders() {}\n\n  public interface VariantValueReader extends ParquetValueReader<VariantValue> {\n    @Override\n    default VariantValue read(VariantValue reuse) {\n      throw new UnsupportedOperationException(\"Variants must be read using read(VariantMetadata)\");\n    }\n\n    /** Reads a variant value */\n    VariantValue read(VariantMetadata metadata);\n  }\n\n  private static final VariantValue MISSING = null;\n\n  @SuppressWarnings(\"unchecked\")\n  public static ParquetValueReader<Variant> variant(\n      ParquetValueReader<?> metadata, ParquetValueReader<?> value) {\n    return new VariantReader(\n        (ParquetValueReader<VariantMetadata>) metadata, (VariantValueReader) value);\n  }\n\n  public static ParquetValueReader<VariantMetadata> metadata(ColumnDescriptor desc) {\n    return new VariantMetadataReader(desc);\n  }","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/parquet/src/main/java/org/apache/iceberg/parquet/ParquetVariantReaders.java#L31-L67","documentation":"VariantValueReader extends ParquetValueReader but Variants are not read in the normal read(reuse) style. The default read(VariantValue reuse) method deliberately throws UnsupportedOperationException because variant values require VariantMetadata context; callers must use read(VariantMetadata) instead.","triggerScenarios":"Invoking read(reuse) on any VariantValueReader — typically from generic Parquet reader code that treats the variant column like an ordinary primitive, or from copied reader pipelines that call the base interface method.","commonSituations":"Wiring a variant reader into a generic column-reader path that only knows ParquetValueReader.read(reuse); custom engine adapters calling the wrong overload; frameworks iterating readers polymorphically without variant support.","solutions":["Use read(VariantMetadata metadata) and supply the variant metadata obtained from the table/manifest","Ensure the generic reader path dispatches to VariantValueReader specially instead of calling read(reuse)","Upgrade or patch the consuming engine integration to support variants"],"exampleFix":"// before: generic read\nVariantValue v = variantReader.read(null);\n// after: provide metadata\nVariantValue v = variantReader.read(variantMetadata);","handlingStrategy":"type-guard","validationCode":"if (reader instanceof ParquetVariantReaders.VariantValueReader) {\n  // must call read(VariantMetadata), not read(reuse)\n}","typeGuard":"VariantValue readVariant(ParquetValueReader<?> reader, VariantMetadata md) {\n  if (reader instanceof ParquetVariantReaders.VariantValueReader) {\n    return ((ParquetVariantReaders.VariantValueReader) reader).read(md);\n  }\n  throw new IllegalArgumentException(\"Not a variant reader\");\n}","tryCatchPattern":"try {\n  v = reader.read(reuse);\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage().contains(\"Variants must be read using read(VariantMetadata)\")) {\n    v = ((VariantValueReader) reader).read(variantMetadata);\n  } else throw e;\n}","preventionTips":["Route variant columns through variant-aware reader paths","Check instanceof VariantValueReader before generic read(reuse) calls","Keep engine adapters updated for the variant spec"],"tags":["variant","unsupported-operation","parquet"],"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-23T08:17:48.524Z"}