prestodb/presto · error · IllegalArgumentException

isNull length is less than positionCount

Error message

isNull length is less than positionCount

What it means

ShortArrayBlock validates that the optional valueIsNull boolean array is at least arrayOffset + positionCount long whenever it is non-null. If isNull is shorter than the block's position range, null-lookups would read out of bounds, so the constructor throws IllegalArgumentException. The values and isNull arrays must have consistent capacity.

Source

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

    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
    public OptionalInt fixedSizeInBytesPerPosition()
    {
        return OptionalInt.of(SIZE_IN_BYTES_PER_POSITION);
    }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Allocate valueIsNull with length >= arrayOffset + positionCount, mirroring values sizing.
  2. Pass null if no nulls are possible instead of an undersized mask.
  3. Assert Arrays consistency: requireNonNull sizing helper before construction.

Example fix

// before
boolean[] isNull = new boolean[positionCount / 2];
new ShortArrayBlock(arrayOffset, positionCount, values, isNull);
// after
boolean[] isNull = new boolean[arrayOffset + positionCount];
new ShortArrayBlock(arrayOffset, positionCount, values, isNull);
Defensive patterns

Strategy: validation

Validate before calling

if (valueIsNull != null && valueIsNull.length - arrayOffset < positionCount) {
    throw new IllegalArgumentException("valueIsNull too small: need " + (arrayOffset + positionCount) + ", have " + valueIsNull.length);
}

Type guard

boolean nullMaskFits(int arrayOffset, int positionCount, boolean[] valueIsNull) {
    return valueIsNull == null || valueIsNull.length - arrayOffset >= positionCount;
}

Try / catch

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

Prevention

When it happens

Trigger: Constructing ShortArrayBlock with a non-null valueIsNull array where valueIsNull.length - arrayOffset < positionCount.

Common situations: Allocating the null mask from a different length source than the values array (e.g. reusing a stale mask after resizing), copy/paste where only values were grown, corrupted input data.

Related errors


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