prestodb/presto · error · IllegalArgumentException
position is not valid
Error message
position is not valid
What it means
AbstractRowBlock.checkReadablePosition validates that a position argument is within [0, positionCount). Any reader API (copyPositions, getBlock, writePositionTo, getSingleValueBlock, getEstimatedDataSizeForStats) called with an out-of-range position throws IllegalArgumentException with the generic message "position is not valid".
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/AbstractRowBlock.java:382
Block[] rawFieldBlocks = getRawFieldBlocks();
long size = 0;
for (int i = 0; i < numFields; i++) {
size += rawFieldBlocks[i].getEstimatedDataSizeForStats(getFieldBlockOffset(position));
}
return size;
}
@Override
public boolean mayHaveNull()
{
return getRowIsNull() != null;
}
protected final void checkReadablePosition(int position)
{
if (position < 0 || position >= getPositionCount()) {
throw new IllegalArgumentException("position is not valid");
}
}
@Override
public Block getBlockUnchecked(int internalPosition)
{
assert internalPositionInRange(internalPosition, getOffsetBase(), getPositionCount());
return new SingleRowBlock(getFieldBlockOffsets()[internalPosition], getRawFieldBlocks());
}
@Override
public boolean isNullUnchecked(int internalPosition)
{
assert mayHaveNull() : "no nulls present";
assert internalPositionInRange(internalPosition, getOffsetBase(), getPositionCount());
return getRowIsNull()[internalPosition];
}
View on GitHub (pinned to 55bb57d202)
Solutions
- Clamp/bound loop indices with block.getPositionCount() before calling reader methods.
- Verify the position source: only pass positions produced for this same block, not stale or foreign indices.
- Use block iterator or getPositions/processing APIs that enforce bounds automatically.
- Reproduce with the caller stack trace and fix the off-by-one in the operator rather than catching the exception.
Example fix
// before
for (int i = 0; i <= block.getPositionCount(); i++) {
block.writePositionTo(i, output);
}
// after
for (int i = 0; i < block.getPositionCount(); i++) {
block.writePositionTo(i, output);
} Defensive patterns
Strategy: type-guard
Validate before calling
static boolean isValidPosition(Block block, int position) {
return position >= 0 && position < block.getPositionCount();
} Type guard
static boolean hasReadablePosition(Block block, int position) {
return block != null && position >= 0 && position < block.getPositionCount();
} Try / catch
try {
block.writePositionTo(position, output);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().equals("position is not valid")) {
throw new IndexOutOfBoundsException("position " + position + " out of range for block of " + block.getPositionCount());
}
throw e;
} Prevention
- Always bound loops with block.getPositionCount() using strict '<'.
- Track position provenance: only pass positions generated for the same block.
- Prefer Block.getChildren/getBlock slices over manual position arithmetic.
When it happens
Trigger: Calling any of those public reader methods with a negative position, or a position >= the block's position count; commonly from iterating past the end or using positions from a different block.
Common situations: Off-by-one loops in custom operators/expression implementations; using an internal position where an external one is expected; null-handling bugs that skip a position decrement.
Related errors
- position is not valid: " + position
- 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/f40d2d26b63c78bf.
Report an issue: GitHub.