prestodb/presto · error · IllegalArgumentException
Invalid position %s in block with %s positions
Error message
Invalid position %s in block with %s positions
What it means
BlockUtil.checkValidPosition validates a single position index against a block's positionCount, throwing IllegalArgumentException if position is negative or >= positionCount. It protects single-position accessors (isNull, getLong, getSlice, etc.) from reading out of bounds.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/BlockUtil.java:75
static void checkValidRegion(int positionCount, int positionOffset, int length)
{
if (positionOffset < 0 || length < 0 || positionOffset + length > positionCount) {
throw new IndexOutOfBoundsException(format("Invalid position %s and length %s in block with %s positions", positionOffset, length, positionCount));
}
}
static void checkValidPositions(boolean[] positions, int positionCount)
{
if (positions.length != positionCount) {
throw new IllegalArgumentException(format("Invalid positions array size %d, actual position count is %d", positions.length, positionCount));
}
}
static void checkValidPosition(int position, int positionCount)
{
if (position < 0 || position >= positionCount) {
throw new IllegalArgumentException(format("Invalid position %s in block with %s positions", position, positionCount));
}
}
static void checkValidSliceRange(int sourceIndex, int length)
{
//sourceIndex + length can overflow integer range
if (sourceIndex > MAX_ARRAY_SIZE - length) {
throw new SliceTooLargeException(format("Cannot allocate slice larger than %d bytes", MAX_ARRAY_SIZE));
}
}
static int calculateNewArraySize(int currentSize)
{
// grow array by 50%
long newSize = (long) currentSize + (currentSize >> 1);
// verify new size is within reasonable bounds
if (newSize < DEFAULT_CAPACITY) {View on GitHub (pinned to 55bb57d202)
Solutions
- Verify 0 <= position < block.getPositionCount() before accessing positions
- Ensure the position index belongs to the same block/page that produced it (don't reuse indices across pages)
- Catch IllegalArgumentException at the accessor boundary and log position and positionCount
Example fix
// before
if (position <= block.getPositionCount()) {
value = block.getLong(position);
}
// after
if (position >= 0 && position < block.getPositionCount()) {
value = block.getLong(position);
} Defensive patterns
Strategy: type-guard
Validate before calling
checkArgument(position >= 0 && position < block.getPositionCount(), "position %s out of [0,%s)", position, block.getPositionCount());
Type guard
boolean isValidPosition(Block block, int position) {
return position >= 0 && position < block.getPositionCount();
} Try / catch
try {
long v = block.getLong(position);
} catch (IllegalArgumentException e) {
throw new PrestoException(GENERIC_INTERNAL_ERROR, "position " + position + " invalid for block of " + block.getPositionCount(), e);
} Prevention
- Loop with i < block.getPositionCount(), never <=
- Do not reuse row indices across different blocks or pages
- Check offsets before/after compaction operations that shift positions
When it happens
Trigger: Calling block.isNull(pos)/getLong(pos)/getSlice(pos) with a position from a stale row index, from a page that was already consumed/compacted, or from iterating with wrong bounds (e.g. < positionCount+1).
Common situations: Operator loops using an off-by-one upper bound; row-number references into blocks that have since been compacted; mixing positions between blocks in a page with differing position counts.
Related errors
- Invalid positions array size %d, actual position count is %d
- dictionarySourceIds must be the same
- blocks is empty
- Column does not have same position count (%s) as page (%s)
- QualifiedObjectName should have exactly 3 parts, found %s: %
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/5049270d81761dfd.
Report an issue: GitHub.