prestodb/presto · error · IllegalArgumentException
position is not valid
Error message
position is not valid
What it means
ByteArrayBlock.checkReadablePosition throws IllegalArgumentException when a caller asks for a position outside the valid range [0, getPositionCount()). Read APIs such as getByte, isNull, writePositionTo, getSingleValueBlock, copyPositions and toLong all funnel through this guard so the block never reads out of bounds.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/ByteArrayBlock.java:249
return new ByteArrayBlock(0, length, newValueIsNull, newValues);
}
@Override
public String getEncodingName()
{
return ByteArrayBlockEncoding.NAME;
}
@Override
public String toString()
{
return format("ByteArrayBlock(%d){positionCount=%d}", hashCode(), getPositionCount());
}
private void checkReadablePosition(int position)
{
if (position < 0 || position >= getPositionCount()) {
throw new IllegalArgumentException("position is not valid");
}
}
@Override
public int getOffsetBase()
{
return arrayOffset;
}
@Override
public boolean isNullUnchecked(int internalPosition)
{
assert mayHaveNull() : "no nulls present";
assert internalPositionInRange(internalPosition, getOffsetBase(), getPositionCount());
return valueIsNull[internalPosition];
}
@OverrideView on GitHub (pinned to 55bb57d202)
Solutions
- Clamp/bound loops with block.getPositionCount() rather than an external row count
- Check 0 <= position && position < block.getPositionCount() before each read
- Verify the positions array passed to copyPositions contains only indexes within range
- Trace where the invalid position originates — usually an upstream page or operator produced fewer rows than expected
Example fix
// before for (int i = 0; i < expectedRows; i++) value = block.getByte(i); // may throw // after for (int i = 0; i < block.getPositionCount(); i++) value = block.getByte(i);
Defensive patterns
Strategy: validation
Validate before calling
if (position < 0 || position >= block.getPositionCount()) {
throw new IllegalArgumentException("position " + position + " out of range [0, " + block.getPositionCount() + ")");
}
byte value = block.getByte(position);
Type guard
boolean isReadablePosition(Block block, int position) {
return position >= 0 && position < block.getPositionCount();
}
Try / catch
try {
byte v = block.getByte(position);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("position is not valid")) {
throw new IllegalStateException("read past block end; positionCount=" + block.getPositionCount());
}
throw e;
}
Prevention
- Iterate with i < block.getPositionCount(), never with external expected-row counts
- Re-read positionCount after any operation that may trim/reassign the block
- Validate positions arrays before copyPositions
When it happens
Trigger: Calling block.getByte(position) or block.isNull(position) with position < 0 or position >= block.getPositionCount(); iterating with a stale/hardcoded position count; copyPositions with a positions array containing out-of-range indexes; using a position from a different (larger) block.
Common situations: Loops bounded by a wrong variable (e.g. logical row count vs physical block positionCount); aggregating blocks from pages with differing row counts after a filter; operator code caching a positionCount before a block was trimmed or reassigned.
Related errors
- position is not valid
- position is not valid
- position is not valid: " + position
- position is not valid: " + position
- position is not valid
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/2bd212ddb41b6082.
Report an issue: GitHub.