prestodb/presto · error · IllegalArgumentException
positionCount is negative
Error message
positionCount is negative
What it means
A block cannot have a negative number of positions. The Int128ArrayBlock constructor validates positionCount >= 0 and throws IllegalArgumentException if it is negative, since all downstream reads iterate that many positions.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/Int128ArrayBlock.java:69
@Nullable
private final boolean[] valueIsNull;
private final long[] values;
private final long retainedSizeInBytes;
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()View on GitHub (pinned to 55bb57d202)
Solutions
- Clamp the computed count: int count = Math.max(0, end - start).
- Assert end >= start before constructing the block so the real bug (wrong range order) surfaces at the source.
- If the count came from serialized data, validate it against the remaining buffer size before use.
Example fix
// before Int128ArrayBlock block = new Int128ArrayBlock(0, end - start, isNull, values); // after checkArgument(end >= start, "invalid range [%s, %s)", start, end); Int128ArrayBlock block = new Int128ArrayBlock(0, end - start, isNull, values);
Defensive patterns
Strategy: validation
Validate before calling
checkArgument(end >= start, "invalid range [%s, %s): positionCount would be negative", start, end); int positionCount = end - start;
Type guard
boolean validPositionCount(int positionCount) { return positionCount >= 0; } Try / catch
try {
block = new Int128ArrayBlock(0, positionCount, isNull, values);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("positionCount is negative")) {
throw new IllegalStateException("range computation gave negative count " + positionCount, e);
}
throw e;
} Prevention
- Order-check start/end before subtraction.
- If counts come from serialized pages, validate them against remaining payload size.
- Use checkArgument-style guards at every block construction site.
When it happens
Trigger: Constructing Int128ArrayBlock with a negative positionCount, usually from a subtraction like endPosition - startPosition where end < start, or an uninitialized count variable.
Common situations: Page splitting/merging code where range arithmetic went backwards; off-by-one fixes that inverted a subtraction; deserializers reading a corrupt negative count from a serialized page.
Related errors
- positionOffset is negative
- arrayOffset is negative
- positionCount is negative
- Offset is not monotonically ascending. offsets[%s]=%s, offse
- A null map must have zero entries
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/cded4ee7cb723a14.
Report an issue: GitHub.