prestodb/presto · error · IllegalArgumentException
arrayOffset is negative
Error message
arrayOffset is negative
What it means
IntArrayBlock's package constructor validates arrayOffset, the starting index into the shared values/valueIsNull arrays. A negative arrayOffset would make all position indexing read before the start of the backing arrays, so the constructor throws IllegalArgumentException immediately.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/IntArrayBlock.java:59
public static final int SIZE_IN_BYTES_PER_POSITION = Integer.BYTES + Byte.BYTES;
private final int arrayOffset;
private final int positionCount;
@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);View on GitHub (pinned to 55bb57d202)
Solutions
- Ensure the arrayOffset passed is >= 0; check the computation that produces it.
- Use the public two-arg constructor IntArrayBlock(positionCount, valueIsNull, values) which defaults arrayOffset to 0 when slicing is not needed.
- Clamp negative offsets to 0 only if the underlying arrays actually start at index 0 (otherwise the data is misaligned — fix the producer).
Example fix
// before int offset = sliceStart - headerSize; // may be negative IntArrayBlock block = new IntArrayBlock(offset, count, nulls, values); // after int offset = Math.max(0, sliceStart - headerSize); IntArrayBlock block = new IntArrayBlock(offset, count, nulls, values);
Defensive patterns
Strategy: validation
Validate before calling
if (arrayOffset < 0) {
throw new IllegalArgumentException("arrayOffset must be non-negative");
}
IntArrayBlock block = new IntArrayBlock(arrayOffset, positionCount, valueIsNull, values); Type guard
boolean validBlockArgs(int arrayOffset, int positionCount, int[] values) {
return arrayOffset >= 0 && positionCount >= 0 && values.length - arrayOffset >= positionCount;
} Try / catch
try {
block = new IntArrayBlock(offset, count, nulls, values);
} catch (IllegalArgumentException e) {
block = new IntArrayBlock(count, Optional.empty(), values); // compact fallback
} Prevention
- Prefer the public constructor that omits arrayOffset when not slicing
- Check offset arithmetic (base - delta) for underflow
- Assert offsets are non-negative in buffer-segment utilities
When it happens
Trigger: Constructing IntArrayBlock (directly or via the compact wrapper) with a negative arrayOffset, typically from slice.getArrayOffset()-style computations that produced -1 on failure or from manual offset arithmetic that underflowed.
Common situations: Block factory code reusing buffer segments where offset is computed as base - delta and delta exceeds base; wrapping subarrays after an empty-slice getArrayOffset() returning unexpected values.
Related errors
- positionCount 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/ac156fe427414aee.
Report an issue: GitHub.