prestodb/presto · error · IllegalArgumentException
values length is less than positionCount
Error message
values length is less than positionCount
What it means
Int128 values occupy 2 longs each, so the values array must hold at least positionCount*2 longs beyond the positionOffset (which is also in positions, i.e. offset*2 longs). The constructor throws IllegalArgumentException when the backing array is too small, preventing out-of-bounds reads later.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/Int128ArrayBlock.java:74
public Int128ArrayBlock(int positionCount, Optional<boolean[]> valueIsNull, long[] values)
{
this(0, positionCount, valueIsNull.orElse(null), values);
}
Int128ArrayBlock(int positionOffset, int positionCount, boolean[] valueIsNull, long[] values)
{
if (positionOffset < 0) {
throw new IllegalArgumentException("positionOffset is negative");
}
this.positionOffset = positionOffset;
if (positionCount < 0) {
throw new IllegalArgumentException("positionCount is negative");
}
this.positionCount = positionCount;
if (values.length - (positionOffset * 2) < positionCount * 2) {
throw new IllegalArgumentException("values length is less than positionCount");
}
this.values = values;
if (valueIsNull != null && valueIsNull.length - positionOffset < 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;
}
@OverrideView on GitHub (pinned to 55bb57d202)
Solutions
- Allocate values with capacity 2 * (positionOffset + positionCount) longs.
- Double-check every allocation site for Int128 blocks multiplies the position count by 2 (INT128 = two longs).
- If reusing a buffer, grow it (Arrays.copyOf) when values.length < 2 * (positionOffset + positionCount).
Example fix
// before long[] values = new long[positionCount]; // too small for 128-bit values // after long[] values = new long[2 * (positionOffset + positionCount)];
Defensive patterns
Strategy: validation
Validate before calling
checkArgument(values.length >= 2 * (positionOffset + positionCount),
"values array too small: need %d longs for %d INT128 positions, got %d",
2 * (positionOffset + positionCount), positionCount, values.length); Type guard
boolean valuesSizedForInt128(long[] values, int positionOffset, int positionCount) {
return values.length >= 2 * (positionOffset + positionCount);
} Try / catch
try {
block = new Int128ArrayBlock(offset, count, isNull, values);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("values length is less than positionCount")) {
values = Arrays.copyOf(values, 2 * (offset + count));
block = new Int128ArrayBlock(offset, count, isNull, values);
} else { throw e; }
} Prevention
- Remember INT128 needs 2 longs per position — multiply by 2 in every allocation.
- Centralize Int128 buffer allocation in one helper to avoid per-site mistakes.
- Check that reused/grown buffers account for positionOffset as well as positionCount.
When it happens
Trigger: new Int128ArrayBlock(positionOffset, positionCount, valueIsNull, values) where values.length - positionOffset*2 < positionCount*2 — e.g. allocating values as positionCount longs instead of 2*positionCount, or forgetting to account for a non-zero positionOffset.
Common situations: Custom block builders allocating 1 long per position instead of 2 for 128-bit types (DECIMAL(38,x)); reusing buffers trimmed to a smaller previous batch; slicing code that applies the offset to positions but not to the array length calculation.
Related errors
- positionOffset is negative
- positionCount is negative
- isNull length is less than positionCount
- offset must be 0 or 8
- otherOffset %d, length %d are invalid for otherSlice with le
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/644acd7ada76f9d9.
Report an issue: GitHub.