prestodb/presto · error · IllegalArgumentException

position is not valid

Error message

position is not valid

What it means

checkReadablePosition on IntArrayBlockBuilder validates positions before reads (getByte, isNull, writePositionTo, getSingleValueBlock, copyPositions). A position outside [0, getPositionCount()) throws IllegalArgumentException because the builder holds no value there.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/block/IntArrayBlockBuilder.java:328

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

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

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

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

    @Override
    public boolean isNullUnchecked(int internalPosition)
    {
        assert mayHaveNull() : "no nulls present";
        assert internalPositionInRange(internalPosition, getOffsetBase(), getPositionCount());
        return valueIsNull[internalPosition];
    }

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

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Call closeEntry() for every entry before reading back positions via the builder API.
  2. Bound all loops with position < builder.getPositionCount().
  3. For bulk reads, call builder.build() to get an immutable block and read positions from that block instead.

Example fix

// before
builder.writeByte(v);
boolean n = builder.isNull(builder.getPositionCount()); // not yet closed
// after
builder.writeByte(v);
builder.closeEntry();
boolean n = builder.isNull(builder.getPositionCount() - 1);
Defensive patterns

Strategy: validation

Validate before calling

if (position >= 0 && position < builder.getPositionCount()) {
    value = builder.getByte(position);
}

Type guard

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

Try / catch

try {
    value = builder.isNull(position);
} catch (IllegalArgumentException e) {
    value = null; // position not yet written
}

Prevention

When it happens

Trigger: Reading a builder position that hasn't been written yet (positionCount only advances after closeEntry), position == positionCount during an in-progress append loop, or negative/stale indexes from another block.

Common situations: Reading values from a builder mid-build before entries are closed; iterating with an off-by-one bound; reusing row indexes after the builder was reset or used to build a new block instance.

Related errors


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