prestodb/presto · error · IllegalArgumentException

position is not valid

Error message

position is not valid

What it means

AbstractSingleArrayBlock.checkReadablePosition validates that a position passed to element accessors (getSliceLength, getByte, getShort, getInt, getLong, getSlice) lies within [0, getPositionCount()). An out-of-range position throws IllegalArgumentException "position is not valid". Note positions here index the array elements of the single-element array block, not the underlying array.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/block/AbstractSingleArrayBlock.java:36

import static com.facebook.presto.common.block.BlockUtil.internalPositionInRange;

public abstract class AbstractSingleArrayBlock
        implements Block
{
    protected final int start;

    protected AbstractSingleArrayBlock(int start)
    {
        this.start = start;
    }

    protected abstract Block getBlock();

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

    @Override
    public int getSliceLength(int position)
    {
        checkReadablePosition(position);
        return getBlock().getSliceLength(position + start);
    }

    @Override
    public byte getByte(int position)
    {
        checkReadablePosition(position);
        return getBlock().getByte(position + start);
    }

    @Override

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Bound loops by getPositionCount() of the AbstractSingleArrayBlock (array size), not the underlying value block.
  2. Use ArrayBlock.getUnderlyingValueBlock/position mapping helpers to convert positions when crossing block boundaries.
  3. Validate index expressions in the operator that produced the subscript before reading elements.

Example fix

// before
Block arrayBlock = ...;
for (int i = 0; i < rawArray.getPositionCount(); i++) {
    process(arrayBlock, i); // wrong position space
}
// after
for (int i = 0; i < arrayBlock.getPositionCount(); i++) {
    process(arrayBlock, i);
}
Defensive patterns

Strategy: type-guard

Validate before calling

static boolean isValidArrayPosition(Block arrayBlock, int position) {
    return position >= 0 && position < arrayBlock.getPositionCount();
}

Type guard

static boolean canRead(Block singleArrayBlock, int position) {
    return position >= 0 && position < singleArrayBlock.getPositionCount();
}

Try / catch

try {
    long v = arrayBlock.getLong(position);
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().equals("position is not valid")) {
        throw new IndexOutOfBoundsException("array element index out of range: " + position);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling element getters with position < 0 or >= the array element count, e.g. using the raw array block's positions or iterating over the wrong size.

Common situations: Expression evaluators mis-computing element positions inside array access; off-by-one loops over array elements; confusing the single-array block position space with the underlying block's position space.

Related errors


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