prestodb/presto · error · IllegalArgumentException

position is not valid

Error message

position is not valid

What it means

checkReadablePosition on IntArrayBlock guards all position-based reads (getInt, isNull, writePositionTo, getSingleValueBlock, copyPositions, toLong). Positions must be in [0, getPositionCount()); anything else throws IllegalArgumentException since that position does not exist in the block.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/block/IntArrayBlock.java:242

        return new IntArrayBlock(0, length, newValueIsNull, newValues);
    }

    @Override
    public String getEncodingName()
    {
        return IntArrayBlockEncoding.NAME;
    }

    @Override
    public String toString()
    {
        return format("IntArrayBlock(%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];
    }

    @Override

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Bound loops with position < block.getPositionCount().
  2. Validate positions copied from another block against this block's count before use.
  3. Use getRegion/copyPositions for bulk access rather than manual per-position reads across blocks.

Example fix

// before
int v = block.getInt(page.getPositionCount() - 1 + 1); // one past end
// after
int last = block.getPositionCount() - 1;
if (last >= 0) { int v = block.getInt(last); }
Defensive patterns

Strategy: validation

Validate before calling

if (position < 0 || position >= block.getPositionCount()) {
    return null; // skip invalid read
}
int v = block.getInt(position);

Type guard

boolean readablePosition(Block b, int position) {
    return position >= 0 && position < b.getPositionCount();
}

Try / catch

try {
    v = block.getInt(position);
} catch (IllegalArgumentException e) {
    throw new IllegalStateException("Block position " + position + " invalid for count " + block.getPositionCount(), e);
}

Prevention

When it happens

Trigger: Calling any read API with position < 0 or position >= getPositionCount() — e.g. iterating with i <= count, reading a position from a different (larger) block, or stale indexes after slicing with arrayOffset.

Common situations: Off-by-one loops; cross-block position reuse after copyPositions/getRegion; operator restart code reading cached row indexes against a rebuilt page.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/0646fc2bb0fffe61. Report an issue: GitHub.