prestodb/presto · error · IllegalArgumentException
positionCount is negative
Error message
positionCount is negative
What it means
IntArrayBlock requires a non-negative positionCount. Negative counts are impossible block sizes and indicate a caller bug (e.g. subtracting lengths or passing a sentinel), so the constructor throws IllegalArgumentException before any data is stored.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/IntArrayBlock.java:63
@Nullable
private final boolean[] valueIsNull;
private final int[] values;
private final long retainedSizeInBytes;
public IntArrayBlock(int positionCount, Optional<boolean[]> valueIsNull, int[] values)
{
this(0, positionCount, valueIsNull.orElse(null), values);
}
IntArrayBlock(int arrayOffset, int positionCount, boolean[] valueIsNull, int[] 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()View on GitHub (pinned to 55bb57d202)
Solutions
- Validate end >= start (or count >= 0) before constructing the block.
- Fix the arithmetic that derives positionCount (e.g. Math.abs is wrong — correct the subtraction order).
- Sanitize counts read from external/serialized sources before constructing blocks.
Example fix
// before int count = endIdx - startIdx; // endIdx < startIdx -> negative // after int count = Math.max(0, endIdx - startIdx);
Defensive patterns
Strategy: validation
Validate before calling
if (positionCount < 0) {
throw new IllegalArgumentException("positionCount must be non-negative");
}
IntArrayBlock block = new IntArrayBlock(arrayOffset, positionCount, valueIsNull, values); Type guard
boolean nonNegativeCount(int positionCount) { return positionCount >= 0; } Try / catch
try {
block = new IntArrayBlock(offset, count, nulls, values);
} catch (IllegalArgumentException e) {
block = IntArrayBlock.EMPTY_BLOCK; // or recompute count
} Prevention
- Verify end >= start in slice arithmetic before computing counts
- Sanitize counts read from serialized or external data
- Use Math.max(0, end - start) defensively where ordering isn't guaranteed
When it happens
Trigger: Calling new IntArrayBlock(arrayOffset, positionCount, ...) with positionCount < 0, usually from length arithmetic like end - start where end < start.
Common situations: Slicing pages where start/end indexes got swapped; aggregate code subtracting consumed positions from a smaller total; deserializers reading a corrupted negative count field.
Related errors
- arrayOffset is negative
- Offset is not monotonically ascending. offsets[%s]=%s, offse
- A null map must have zero entries
- Number of fields in RowBlock must be positive
- position is not valid
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/73b904818262b01f.
Report an issue: GitHub.