prestodb/presto · error · IllegalArgumentException

values length is less than positionCount

Error message

values length is less than positionCount

What it means

ShortArrayBlock's constructor checks that the backing short[] values array is at least arrayOffset + positionCount long. If values.length - arrayOffset < positionCount the block would read out of bounds, so the constructor rejects it with IllegalArgumentException. This protects all position reads against buffer overruns.

Source

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

    public ShortArrayBlock(int positionCount, Optional<boolean[]> valueIsNull, short[] values)
    {
        this(0, positionCount, valueIsNull.orElse(null), values);
    }

    ShortArrayBlock(int arrayOffset, int positionCount, boolean[] valueIsNull, short[] values)
    {
        if (arrayOffset < 0) {
            throw new IllegalArgumentException("arrayOffset is negative");
        }
        this.arrayOffset = arrayOffset;
        if (positionCount < 0) {
            throw new IllegalArgumentException("positionCount is negative");
        }
        this.positionCount = positionCount;

        if (values.length - arrayOffset < positionCount) {
            throw new IllegalArgumentException("values length is less than positionCount");
        }
        this.values = values;

        if (valueIsNull != null && valueIsNull.length - arrayOffset < positionCount) {
            throw new IllegalArgumentException("isNull length is less than positionCount");
        }
        this.valueIsNull = valueIsNull;

        retainedSizeInBytes = INSTANCE_SIZE + sizeOf(valueIsNull) + sizeOf(values);
    }

    @Override
    public long getSizeInBytes()
    {
        return SIZE_IN_BYTES_PER_POSITION * (long) positionCount;
    }

    @Override

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Size the values array to at least arrayOffset + positionCount before construction.
  2. Recompute positionCount as values.length - arrayOffset when intending to consume the whole array.
  3. Check serialization/deserialization of the array for truncation.

Example fix

// before
short[] values = new short[positionCount - 1]; // too small
new ShortArrayBlock(arrayOffset, positionCount, values, valueIsNull);
// after
short[] values = new short[arrayOffset + positionCount];
new ShortArrayBlock(arrayOffset, positionCount, values, valueIsNull);
Defensive patterns

Strategy: validation

Validate before calling

if (values.length - arrayOffset < positionCount) {
    throw new IllegalArgumentException("values too small: need " + (arrayOffset + positionCount) + ", have " + values.length);
}

Type guard

boolean valuesFit(int arrayOffset, int positionCount, short[] values) {
    return values != null && values.length - arrayOffset >= positionCount;
}

Try / catch

try {
    block = new ShortArrayBlock(arrayOffset, positionCount, values, valueIsNull);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("values length is less than positionCount")) {
        values = Arrays.copyOf(values, arrayOffset + positionCount);
        block = new ShortArrayBlock(arrayOffset, positionCount, values, valueIsNull);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Constructing ShortArrayBlock where values.length - arrayOffset < positionCount, e.g. passing a truncated array or an oversized positionCount.

Common situations: Slicing code that splits an array by positions but sizes the new array too small, aggregation of multiple segments where lengths were summed incorrectly, or corrupted serialized input.

Related errors


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