prestodb/presto · error · IllegalArgumentException

position is not valid

Error message

position is not valid

What it means

checkReadablePosition guards every positional read on ShortArrayBlock (getShort, isNull, writePositionTo, getSingleValueBlock, copyPositions, etc.). Any position outside [0, positionCount) is invalid and throws IllegalArgumentException("position is not valid"). It prevents silent out-of-bounds access into the internal values array.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/block/ShortArrayBlock.java:240

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

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

    @Override
    public String toString()
    {
        return format("ShortArrayBlock(%d){positionCount=%d}", hashCode(), getPositionCount());
    }

    private void checkReadablePosition(int position)
    {
        if (position < 0 || position >= getPositionCount()) {
            throw new IllegalArgumentException("position is not valid");
        }
    }

    @Override
    public short getShortUnchecked(int internalPosition)
    {
        assert internalPositionInRange(internalPosition, getOffsetBase(), getPositionCount());
        return values[internalPosition];
    }

    @Override
    public int getOffsetBase()
    {
        return arrayOffset;
    }

    @Override
    public boolean isNullUnchecked(int internalPosition)

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Clamp the loop to positionCount: for (int i = 0; i < block.getPositionCount(); i++).
  2. When working with sliced blocks, convert outer positions to internal ones (position - getRangeStartOffset) before reading.
  3. Null-check or bounds-check the position before calling the accessor.

Example fix

// before
for (int i = 0; i <= block.getPositionCount(); i++) {
    short v = block.getShort(i, 0);
}
// after
for (int i = 0; i < block.getPositionCount(); i++) {
    short v = block.getShort(i, 0);
}
Defensive patterns

Strategy: validation

Validate before calling

if (position < 0 || position >= block.getPositionCount()) {
    throw new IllegalArgumentException("position " + position + " out of range [0, " + block.getPositionCount() + ")");
}

Type guard

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

Try / catch

try {
    short v = shortArrayBlock.getShort(position, 0);
} catch (IllegalArgumentException e) {
    if (e.getMessage().equals("position is not valid")) {
        throw new IllegalStateException("Bad position " + position + " for block with " + shortArrayBlock.getPositionCount() + " positions", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling getShort/isNull/writePositionTo/getSingleValueBlock/copyPositions/toLong on a ShortArrayBlock with position < 0 or position >= positionCount.

Common situations: Off-by-one loops using <= positionCount, using a raw position into an enclosing block instead of the sliced block's internal position, iterating a single-value block with stale indices, using absolute row numbers against a sliced/paginated block.

Related errors


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