prestodb/presto · error · IllegalArgumentException
position is not valid: " + position
Error message
position is not valid: " + position
What it means
AbstractSingleRowBlock.checkFieldIndex validates that a field index passed to accessors (isNull, getByte, getShort, getInt, getLong, getSlice) lies within [0, getPositionCount()). Out-of-range field indices throw IllegalArgumentException with the offending index included in the message.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/AbstractSingleRowBlock.java:37
import static com.facebook.presto.common.block.BlockUtil.internalPositionInRange;
public abstract class AbstractSingleRowBlock
implements Block
{
protected final int rowIndex;
protected AbstractSingleRowBlock(int rowIndex)
{
this.rowIndex = rowIndex;
}
protected abstract Block getRawFieldBlock(int fieldIndex);
private void checkFieldIndex(int position)
{
if (position < 0 || position >= getPositionCount()) {
throw new IllegalArgumentException("position is not valid: " + position);
}
}
@Override
public boolean isNull(int position)
{
checkFieldIndex(position);
return getRawFieldBlock(position).isNull(rowIndex);
}
@Override
public byte getByte(int position)
{
checkFieldIndex(position);
return getRawFieldBlock(position).getByte(rowIndex);
}
@OverrideView on GitHub (pinned to 55bb57d202)
Solutions
- Verify the field ordinal comes from the same RowType used to build the single-row block.
- Fix plan/schema mismatches: clear caches or restart after connector metadata changes so blocks and their types agree.
- Add bounds checks against rowType.getFields().size() in custom evaluation code.
Example fix
// before
int field = fieldNameToIndex.get("new_column"); // not present in block's row type
rowBlock.getLong(field);
// after
if (field < 0 || field >= rowBlock.getPositionCount()) {
throw new IllegalStateException("field ordinal out of range for row type");
}
rowBlock.getLong(field); Defensive patterns
Strategy: type-guard
Validate before calling
static boolean isValidFieldIndex(Block singleRowBlock, int fieldIndex) {
return fieldIndex >= 0 && fieldIndex < singleRowBlock.getPositionCount();
} Type guard
static boolean hasField(RowType rowType, int ordinal) {
return ordinal >= 0 && ordinal < rowType.getFields().size();
} Try / catch
try {
long v = rowBlock.getLong(fieldIndex);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("position is not valid")) {
throw new IndexOutOfBoundsException("field ordinal out of range: " + e.getMessage());
}
throw e;
} Prevention
- Resolve field ordinals from the same RowType instance used to create the block.
- Handle connector metadata changes by invalidating cached plans/blocks.
- Check ordinal bounds in generated expression code before dereference.
When it happens
Trigger: Calling field accessors with index < 0 or >= the number of row fields, e.g. from a RowType field ordinal computed against a different row type, or evaluating a field reference against a mismatched block.
Common situations: Expression compiler bugs mapping dereference ordinals to wrong row types; schema drift where the query plan's row type has more fields than the block's row type (e.g. after connector metadata changes).
Related errors
- position is not valid
- Number of fields in RowBlock must be positive
- position is not valid
- position is not valid: " + position
- otherOffset %d, length %d are invalid for otherSlice with le
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/39c43537f556ba05.
Report an issue: GitHub.