prestodb/presto · error · IllegalArgumentException
positionOffset is negative
Error message
positionOffset is negative
What it means
Int128ArrayBlock supports viewing a sub-range of the underlying long[] via positionOffset. A negative offset is meaningless, so the package-private constructor throws IllegalArgumentException immediately.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/Int128ArrayBlock.java:65
public static final int SIZE_IN_BYTES_PER_POSITION = INT128_BYTES + Byte.BYTES;
private final int positionOffset;
private final int positionCount;
@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);View on GitHub (pinned to 55bb57d202)
Solutions
- Clamp or recompute the offset before construction: ensure positionOffset >= 0 (e.g. Math.max(0, start)).
- If the region logically starts before the buffer, slice the arrays correctly and pass offset 0 with adjusted arrays.
- Validate upstream arithmetic that produced the offset.
Example fix
// before Int128ArrayBlock block = new Int128ArrayBlock(regionStart, count, isNull, values); // regionStart < 0 // after int safeStart = Math.max(0, regionStart); Int128ArrayBlock block = new Int128ArrayBlock(safeStart, count, isNull, values);
Defensive patterns
Strategy: validation
Validate before calling
checkArgument(positionOffset >= 0, "positionOffset must be >= 0, got %s", positionOffset);
Type guard
boolean validOffset(int positionOffset) { return positionOffset >= 0; } Try / catch
try {
block = new Int128ArrayBlock(offset, count, isNull, values);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("positionOffset is negative")) {
throw new IllegalStateException("region arithmetic produced negative offset " + offset, e);
}
throw e;
} Prevention
- Clamp region starts with Math.max(0, start) before constructing blocks.
- Add assertions on offset arithmetic in slicing code.
- Never pass computed offsets straight into block constructors without a bounds check.
When it happens
Trigger: Constructing Int128ArrayBlock directly (or via a region/view helper) with a negative positionOffset, e.g. a computed region start like parentOffset - delta that went below zero.
Common situations: Operator code computing slice offsets with signed arithmetic (subtraction on region starts), page slicing where a start position was clamped incorrectly, custom serializers building blocks from partially filled buffers.
Related errors
- positionCount 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/b08dd4c522ee1e61.
Report an issue: GitHub.