prestodb/presto · error · IllegalArgumentException
block position count (%s) is not equal to number of fields (
Error message
block position count (%s) is not equal to number of fields (%s)
What it means
appendStructure copies a single-row block field-by-field into the builder, so the incoming block's position count must equal the builder's declared number of fields (numFields). A mismatch means the block's layout cannot map onto the row type, so the library throws IllegalArgumentException with both counts.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/RowBlockBuilder.java:279
public String toString()
{
return format("RowBlockBuilder(%d){numFields=%d, positionCount=%d", hashCode(), numFields, getPositionCount());
}
@Override
public BlockBuilder appendStructure(Block block)
{
if (!(block instanceof AbstractSingleRowBlock)) {
throw new IllegalStateException("Expected AbstractSingleRowBlock");
}
if (currentEntryOpened) {
throw new IllegalStateException("Expected current entry to be closed but was opened");
}
currentEntryOpened = true;
int blockPositionCount = block.getPositionCount();
if (blockPositionCount != numFields) {
throw new IllegalArgumentException(format("block position count (%s) is not equal to number of fields (%s)", blockPositionCount, numFields));
}
for (int i = 0; i < blockPositionCount; i++) {
if (block.isNull(i)) {
fieldBlockBuilders[i].appendNull();
}
else {
block.writePositionTo(i, fieldBlockBuilders[i]);
}
}
closeEntry();
return this;
}
@Override
public BlockBuilder appendStructureInternal(Block block, int position)
{
if (!(block instanceof AbstractRowBlock)) {View on GitHub (pinned to 55bb57d202)
Solutions
- Verify block.getPositionCount() equals the row type's field count before appending
- Ensure the RowType/TypeSignature used to create the builder matches the block's row type
- Rebuild the block with the current row type if the schema changed
- Use row field mapping/translation code for schema evolution instead of direct append
Example fix
// before // builder created for RowType(a, b); block has 3 fields rowBuilder.appendStructure(block); // IllegalArgumentException: 3 != 2 // after checkArgument(block.getPositionCount() == rowBuilder.getNumFields(), "row arity mismatch"); rowBuilder.appendStructure(block);
Defensive patterns
Strategy: validation
Validate before calling
// before appendStructure, verify arity matches the builder's row type
if (block.getPositionCount() != expectedNumFields) {
throw new IllegalArgumentException(format(
"row arity mismatch: block has %s fields, builder expects %s",
block.getPositionCount(), expectedNumFields));
}
Try / catch
try {
rowBuilder.appendStructure(block);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("is not equal to number of fields")) {
// rebuild the row with the expected type rather than appending directly
throw new IllegalStateException("row type of block does not match builder type; remap fields", e);
}
throw e;
} Prevention
- Compare block.getPositionCount() with the row type's field count before appending
- Keep row TypeSignature and builder construction from the same Type object
- Handle schema evolution explicitly instead of reusing old blocks
- Add arity assertions in serialization tests
When it happens
Trigger: Passing a single-row block built from a different row type (different arity) to appendStructure, e.g. appending a 3-field row into a 2-field row builder after a schema/type change.
Common situations: Schema evolution where a row type gained/lost fields but upstream blocks were built with the old type; dynamic row types whose field count differs across connectors or catalog versions.
Related errors
- Expected AbstractSingleRowBlock
- Number of fields in RowBlock must be positive
- Invalid field position selection after nulls removed: " + se
- position is not valid
- position is not valid: " + position
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/48915717140e4c72.
Report an issue: GitHub.