{"record":{"id":"df2e36d096648a11","repo":"apache/iceberg","slug":"unsupported-value-for-variant-in-structinternalrow-df2e36","errorCode":null,"errorMessage":"Unsupported value for VARIANT in StructInternalRow: ","messagePattern":"Unsupported value for VARIANT in StructInternalRow: ","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java","lineNumber":411,"sourceCode":"\n    throw new UnsupportedOperationException(\"Unsupported BinaryView type: \" + type);\n  }\n\n  private static VariantVal toVariantVal(Object value) {\n    if (value instanceof Variant) {\n      Variant variant = (Variant) value;\n      byte[] metadataBytes = new byte[variant.metadata().sizeInBytes()];\n      ByteBuffer metadataBuffer = ByteBuffer.wrap(metadataBytes).order(ByteOrder.LITTLE_ENDIAN);\n      variant.metadata().writeTo(metadataBuffer, 0);\n\n      byte[] valueBytes = new byte[variant.value().sizeInBytes()];\n      ByteBuffer valueBuffer = ByteBuffer.wrap(valueBytes).order(ByteOrder.LITTLE_ENDIAN);\n      variant.value().writeTo(valueBuffer, 0);\n\n      return new VariantVal(valueBytes, metadataBytes);\n    }\n\n    throw new UnsupportedOperationException(\n        \"Unsupported value for VARIANT in StructInternalRow: \" + value.getClass());\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private <T> GenericArrayData fillArray(\n      Collection<?> values, Function<Object[], BiConsumer<Integer, T>> makeSetter) {\n    Object[] array = new Object[values.size()];\n    BiConsumer<Integer, T> setter = makeSetter.apply(array);\n\n    int index = 0;\n    for (Object value : values) {\n      if (value == null) {\n        array[index] = null;\n      } else {\n        setter.accept(index, (T) value);\n      }\n\n      index += 1;","sourceCodeStart":393,"sourceCodeEnd":429,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java#L393-L429","documentation":"toVariantVal converts stored variant values into Spark VariantVal, but only accepts Iceberg Variant instances; anything else throws UnsupportedOperationException naming the value's class. This guards the variant decoding path against unexpected internal representations.","triggerScenarios":"Reading a VARIANT column where the value object stored in the row is not an org.apache.iceberg.variants.Variant (e.g. raw byte[], ByteBuffer, or another wrapper) in StructInternalRow.","commonSituations":"Version skew between writer and reader internal variant representations; custom readers that put non-Variant objects into variant fields; bug in value materialization for variant columns.","solutions":["Ensure reader and writer Iceberg versions are compatible for variant columns","Wrap raw variant bytes into an Iceberg Variant before exposing them through the row","Upgrade to a version where variant materialization is fixed"],"exampleFix":"// before: setting raw bytes into a variant column\nrow.set(ordinal, variantBytes);\n// after\nrow.set(ordinal, Variant.tryFrom(variantBytes));","handlingStrategy":"type-guard","validationCode":"if (!(value instanceof Variant)) {\n  throw new IllegalArgumentException(\"VARIANT column value must be an Iceberg Variant: \" + value.getClass());\n}","typeGuard":"static boolean isVariantValue(Object v) {\n  return v instanceof org.apache.iceberg.variants.Variant;\n}","tryCatchPattern":"try {\n  VariantVal vv = row.getVariant(ordinal);\n} catch (UnsupportedOperationException e) {\n  log.error(\"Variant materialization failed: {}\", e.getMessage());\n}","preventionTips":["Align Iceberg versions across writer and reader for variant columns","Don't inject raw bytes into variant fields via custom code paths","Add round-trip tests for variant columns"],"tags":["spark","variant","internal-state"],"backgroundTag":"internal-invariant-violation","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"}