apache/iceberg · error · IllegalArgumentException
Expected one (and same) ORC type for list elements, got: {or
Error message
Expected one (and same) ORC type for list elements, got: {orcTypes} What it means
SparkOrcValueWriters.ListWriter wraps an element writer and expects exactly one ORC TypeDescription describing the list's element type. If orcTypes.size() != 1 the ORC type tree does not match the expected list layout, so the constructor throws IllegalArgumentException to fail fast rather than reading the wrong child types.
Source
Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/data/SparkOrcValueWriters.java:137
}
private static class Decimal38Writer implements OrcValueWriter<Decimal> {
@Override
public void nonNullWrite(int rowId, Decimal decimal, ColumnVector output) {
((DecimalColumnVector) output)
.vector[rowId].set(HiveDecimal.create(decimal.toJavaBigDecimal()));
}
}
private static class ListWriter<T> implements OrcValueWriter<ArrayData> {
private final OrcValueWriter<T> writer;
private final SparkOrcWriter.FieldGetter<T> fieldGetter;
@SuppressWarnings("unchecked")
ListWriter(OrcValueWriter<T> writer, List<TypeDescription> orcTypes) {
if (orcTypes.size() != 1) {
throw new IllegalArgumentException(
"Expected one (and same) ORC type for list elements, got: " + orcTypes);
}
this.writer = writer;
this.fieldGetter =
(SparkOrcWriter.FieldGetter<T>) SparkOrcWriter.createFieldGetter(orcTypes.get(0));
}
@Override
public void nonNullWrite(int rowId, ArrayData value, ColumnVector output) {
ListColumnVector cv = (ListColumnVector) output;
// record the length and start of the list elements
cv.lengths[rowId] = value.numElements();
cv.offsets[rowId] = cv.childCount;
cv.childCount = (int) (cv.childCount + cv.lengths[rowId]);
// make sure the child is big enough
growColumnVector(cv.child, cv.childCount);
// Add each element
for (int e = 0; e < cv.lengths[rowId]; ++e) {View on GitHub (pinned to 86d9c8fc54)
Solutions
- Pass only the element TypeDescription of the ORC list to ListWriter
- Verify the schema mapping produces one child type per list column
- Update Iceberg if the mismatch comes from a fixed mapping bug
- Inspect the ORC schema (TypeDescription.print()) to confirm the list layout
Example fix
// before new ListWriter<>(elemWriter, record.getChildren()) // after new ListWriter<>(elemWriter, record.getChildren().get(0).getChildren())
Defensive patterns
Strategy: try-catch
Validate before calling
List<TypeDescription> children = listType.getChildren();
if (children.size() != 1) {
throw new IllegalStateException("List column must have exactly one element type, got: " + children.size());
} Try / catch
try {
new SparkOrcValueWriters.ListWriter<>(w, orcTypes);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("list elements")) { /* fix the orcTypes slice */ }
else throw e;
} Prevention
- Always derive orcTypes from record.getChildren() of the actual list TypeDescription
- Unit-test schema mapping for nested list columns
- Log ORC TypeDescription trees when debugging writer construction
When it happens
Trigger: Building an ORC ListWriter with a malformed list of child TypeDescriptions — e.g. passing the struct's full child list instead of the list element type, or a corrupted/misaligned schema mapping.
Common situations: Bugs in ORC schema-to-writer mapping code; custom writer plumbing passing the wrong orcTypes slice; ORC files written with non-standard nested type layouts.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Expected one (and same) ORC type for list elements, got:
- Expected two ORC type descriptions for a map, got: {orcTypes
- Expected two ORC type descriptions for a map, got:
- Unhandled type
- Encountered an unsupported ORC type during a write from Spar
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/2c7b7bd2931cb25c.
Report an issue: GitHub.