prestodb/presto · error · IllegalArgumentException

position is not valid: " + position

Error message

position is not valid: " + position

What it means

AbstractSingleRowBlock.checkFieldIndex validates that a field index passed to accessors (isNull, getByte, getShort, getInt, getLong, getSlice) lies within [0, getPositionCount()). Out-of-range field indices throw IllegalArgumentException with the offending index included in the message.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/block/AbstractSingleRowBlock.java:37

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

public abstract class AbstractSingleRowBlock
        implements Block
{
    protected final int rowIndex;

    protected AbstractSingleRowBlock(int rowIndex)
    {
        this.rowIndex = rowIndex;
    }

    protected abstract Block getRawFieldBlock(int fieldIndex);

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

    @Override
    public boolean isNull(int position)
    {
        checkFieldIndex(position);
        return getRawFieldBlock(position).isNull(rowIndex);
    }

    @Override
    public byte getByte(int position)
    {
        checkFieldIndex(position);
        return getRawFieldBlock(position).getByte(rowIndex);
    }

    @Override

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Verify the field ordinal comes from the same RowType used to build the single-row block.
  2. Fix plan/schema mismatches: clear caches or restart after connector metadata changes so blocks and their types agree.
  3. Add bounds checks against rowType.getFields().size() in custom evaluation code.

Example fix

// before
int field = fieldNameToIndex.get("new_column"); // not present in block's row type
rowBlock.getLong(field);
// after
if (field < 0 || field >= rowBlock.getPositionCount()) {
    throw new IllegalStateException("field ordinal out of range for row type");
}
rowBlock.getLong(field);
Defensive patterns

Strategy: type-guard

Validate before calling

static boolean isValidFieldIndex(Block singleRowBlock, int fieldIndex) {
    return fieldIndex >= 0 && fieldIndex < singleRowBlock.getPositionCount();
}

Type guard

static boolean hasField(RowType rowType, int ordinal) {
    return ordinal >= 0 && ordinal < rowType.getFields().size();
}

Try / catch

try {
    long v = rowBlock.getLong(fieldIndex);
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().contains("position is not valid")) {
        throw new IndexOutOfBoundsException("field ordinal out of range: " + e.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling field accessors with index < 0 or >= the number of row fields, e.g. from a RowType field ordinal computed against a different row type, or evaluating a field reference against a mismatched block.

Common situations: Expression compiler bugs mapping dereference ordinals to wrong row types; schema drift where the query plan's row type has more fields than the block's row type (e.g. after connector metadata changes).

Related errors


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