prestodb/presto · error · IllegalArgumentException
Number of fields in RowBlock must be positive
Error message
Number of fields in RowBlock must be positive
What it means
A RowBlock must have at least one field column; the AbstractRowBlock constructor rejects numFields <= 0 because a row type with zero fields cannot be represented in field blocks. This is a construction-time validation of the row type's arity.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/AbstractRowBlock.java:58
public abstract int getOffsetBase();
/**
* @return the underlying rowIsNull array, or null when all rows are guaranteed to be non-null
*/
@Nullable
protected abstract boolean[] getRowIsNull();
// the offset in each field block, it can also be viewed as the "entry-based" offset in the RowBlock
protected final int getFieldBlockOffset(int position)
{
return getFieldBlockOffsets()[position + getOffsetBase()];
}
protected AbstractRowBlock(int numFields)
{
if (numFields <= 0) {
throw new IllegalArgumentException("Number of fields in RowBlock must be positive");
}
this.numFields = numFields;
}
@Override
public String getEncodingName()
{
return RowBlockEncoding.NAME;
}
@Override
public final Block copyPositions(int[] positions, int offset, int length)
{
checkArrayRange(positions, offset, length);
int[] newOffsets = new int[length + 1];
int[] fieldBlockPositions = new int[length];
boolean[] newRowIsNull = null;View on GitHub (pinned to 55bb57d202)
Solutions
- Ensure the RowType has at least one field before constructing the corresponding row block.
- Fix upstream metadata so empty schemas are rejected or given a placeholder field instead of becoming a zero-field row type.
- Guard the code path: if fieldBlocks.length == 0, handle it before calling the block factory.
Example fix
// before
Block[] fieldBlocks = collectFieldBlocks(rowType); // may be empty
RowBlock block = RowBlock.fromFieldBlocks(0, new boolean[] {}, fieldBlocks);
// after
checkState(!rowType.getFields().isEmpty(), "row type must have at least one field");
Block[] fieldBlocks = collectFieldBlocks(rowType);
RowBlock block = RowBlock.fromFieldBlocks(0, new boolean[] {}, fieldBlocks); Defensive patterns
Strategy: validation
Validate before calling
if (fieldBlocks == null || fieldBlocks.length == 0) {
throw new IllegalStateException("cannot build a row block with zero fields");
} Type guard
boolean hasFields(RowType rowType) {
return rowType != null && !rowType.getFields().isEmpty();
} Try / catch
try {
RowBlock block = RowBlock.fromFieldBlocks(positionCount, rowIsNull, fieldBlocks);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("must be positive")) {
throw new SchemaException("row type has no fields", e);
}
throw e;
} Prevention
- Validate RowType arity at metadata load time, before blocks are produced.
- Reject empty column lists at the connector/schema layer.
- Add unit tests for dynamic row type construction.
When it happens
Trigger: Constructing a row block (RowBlock.fromFieldBlocks, encoder/decoder paths) with a RowType that has zero fields, or passing an empty field-block array.
Common situations: Dynamically building a RowType from an empty schema or column list (e.g. a connector returning no columns); metadata/config errors where a row type is created before fields are known.
Related errors
- position is not valid
- position is not valid: " + position
- Offset is not monotonically ascending. offsets[%s]=%s, offse
- A null map must have zero entries
- Invalid field position selection after nulls removed: " + se
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/c0fa46675e76f0cd.
Report an issue: GitHub.