{"record":{"id":"cadd0dfea838bc79","repo":"apache/iceberg","slug":"expected-one-and-same-orc-type-for-list-elements-cadd0d","errorCode":null,"errorMessage":"Expected one (and same) ORC type for list elements, got: ","messagePattern":"Expected one \\(and same\\) ORC type for list elements, got: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/data/SparkOrcValueWriters.java","lineNumber":137,"sourceCode":"  }\n\n  private static class Decimal38Writer implements OrcValueWriter<Decimal> {\n\n    @Override\n    public void nonNullWrite(int rowId, Decimal decimal, ColumnVector output) {\n      ((DecimalColumnVector) output)\n          .vector[rowId].set(HiveDecimal.create(decimal.toJavaBigDecimal()));\n    }\n  }\n\n  private static class ListWriter<T> implements OrcValueWriter<ArrayData> {\n    private final OrcValueWriter<T> writer;\n    private final SparkOrcWriter.FieldGetter<T> fieldGetter;\n\n    @SuppressWarnings(\"unchecked\")\n    ListWriter(OrcValueWriter<T> writer, List<TypeDescription> orcTypes) {\n      if (orcTypes.size() != 1) {\n        throw new IllegalArgumentException(\n            \"Expected one (and same) ORC type for list elements, got: \" + orcTypes);\n      }\n      this.writer = writer;\n      this.fieldGetter =\n          (SparkOrcWriter.FieldGetter<T>) SparkOrcWriter.createFieldGetter(orcTypes.get(0));\n    }\n\n    @Override\n    public void nonNullWrite(int rowId, ArrayData value, ColumnVector output) {\n      ListColumnVector cv = (ListColumnVector) output;\n      // record the length and start of the list elements\n      cv.lengths[rowId] = value.numElements();\n      cv.offsets[rowId] = cv.childCount;\n      cv.childCount = (int) (cv.childCount + cv.lengths[rowId]);\n      // make sure the child is big enough\n      growColumnVector(cv.child, cv.childCount);\n      // Add each element\n      for (int e = 0; e < cv.lengths[rowId]; ++e) {","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/data/SparkOrcValueWriters.java#L119-L155","documentation":"ListWriter in SparkOrcValueWriters builds the ORC writer for a Spark array column. It requires the ORC schema's children list for the list column to contain exactly one element type (the ORC 'list' group has a single 'element' child); anything else means the ORC type tree passed in is malformed or misaligned with the Spark schema. The writer throws IllegalArgumentException during writer construction, before any rows are written.","triggerScenarios":"Calling SparkOrcWriter.createValueWriter (via a write path from Spark) for an array column whose TypeDescription children list has 0 or more than 1 element, e.g. a hand-built ORC TypeDescription whose list group lacks exactly one 'element' child.","commonSituations":"Writing Iceberg ORC files through Spark with a corrupted or externally constructed ORC schema; schema/format mismatches between Iceberg's table schema and the file's ORC type tree; bugs in schema evolution code that reassembles TypeDescription trees.","solutions":["Inspect the ORC schema of the target column (TypeDescription.getChildren()) and ensure the list group has exactly one child element type","Regenerate writers from the Iceberg table schema (spark.table(...).schema()) rather than from a manually constructed ORC type","Check whether a custom ORC schema override/evolution is misaligned with the Spark schema and fix or remove it","If it occurs after a schema evolution, rewrite the affected data files or fix the schema mapping logic"],"exampleFix":"// before\nTypeDescription listType = TypeDescription.createList(nullTypeWithNoChild);\n// after\nTypeDescription elementType = TypeDescription.createLong();\nTypeDescription listType = TypeDescription.createList(elementType); // exactly one child","handlingStrategy":"validation","validationCode":"List<TypeDescription> children = listType.getChildren();\nif (children.size() != 1) {\n  throw new IllegalStateException(\"ORC list type must have exactly one element child, got: \" + listType);\n}","typeGuard":"boolean isValidOrcList(TypeDescription t) {\n  return t.getCategory() == TypeDescription.Category.LIST && t.getChildren().size() == 1;\n}","tryCatchPattern":"try {\n  spark.write().format(\"iceberg\").save(orcTarget);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"Expected one (and same) ORC type for list elements\")) {\n    // validate/repair the ORC schema, then retry\n  } else {\n    throw e;\n  }\n}","preventionTips":["Always derive ORC TypeDescriptions from the Iceberg table schema, never hand-build them","After schema evolution, validate that ORC children lists match the Iceberg types before writing","Add a pre-write unit test asserting writer construction succeeds for every column of the schema"],"tags":["orc","spark","schema","writer-construction"],"backgroundTag":"invalid-argument-value","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"}