prestodb/presto · error · IllegalArgumentException
positionCount is negative
Error message
positionCount is negative
What it means
The ByteArrayBlock constructor rejects a negative positionCount (the number of logical positions in the block). A negative count is meaningless for a block and would corrupt downstream iteration and length checks, so the constructor throws this IllegalArgumentException as a precondition guard.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/ByteArrayBlock.java:70
@Nullable
private final boolean[] valueIsNull;
private final byte[] values;
private final long retainedSizeInBytes;
public ByteArrayBlock(int positionCount, Optional<boolean[]> valueIsNull, byte[] values)
{
this(0, positionCount, valueIsNull.orElse(null), values);
}
ByteArrayBlock(int arrayOffset, int positionCount, boolean[] valueIsNull, byte[] 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
- Fix the count computation so it is non-negative; check for swapped range bounds (ensure end >= start before computing end - start).
- Replace -1 sentinel values with 0 or Optional before constructing the block.
- For an empty block, pass positionCount 0 rather than a negative or sentinel value.
Example fix
// before int count = endIndex - startIndex; // startIndex > endIndex -> negative new ByteArrayBlock(0, count, valueIsNull, values); // after int count = Math.max(0, endIndex - startIndex); checkState(endIndex >= startIndex, "invalid range: start=%s end=%s", startIndex, endIndex); new ByteArrayBlock(0, count, valueIsNull, values);
Defensive patterns
Strategy: validation
Validate before calling
if (positionCount < 0) {
throw new IllegalArgumentException("computed positionCount is negative: " + positionCount);
}
new ByteArrayBlock(arrayOffset, positionCount, valueIsNull, values); Type guard
boolean isValidPositionCount(int positionCount) {
return positionCount >= 0;
} Try / catch
try {
block = new ByteArrayBlock(arrayOffset, positionCount, valueIsNull, values);
} catch (IllegalArgumentException e) {
if (e.getMessage().equals("positionCount is negative")) {
throw new IllegalStateException("negative position count from range [" + start + ", " + end + ")", e);
} else {
throw e;
}
} Prevention
- Check range bounds (end >= start) before computing count = end - start.
- Replace -1 sentinel result sizes with 0 or Optional before constructing blocks.
- Use Math.max(0, end - start) only when an empty result is the intended semantics.
- Watch for int overflow in count arithmetic; use long intermediates for large ranges.
When it happens
Trigger: Constructing ByteArrayBlock with positionCount < 0, typically from a computed count such as end - start where start > end, or from subtraction underflow when deriving position counts from offsets.
Common situations: Slicing code where the range bounds were swapped (from > to); overflow in int arithmetic producing a negative count; connector code passing a result-size variable that was initialized to -1 as a sentinel and never replaced.
Understand the failure class
Background: "must be a positive integer", "cannot be empty", "invalid argument": how invalid-argument errors work across open-source libraries — this error's family across 33 libraries.
Related errors
- arrayOffset is negative
- array1 and array2 cannot be null and should have same length
- positionCount is negative
- ids length is less than positionCount
- New column does not have same number of rows as old column
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/0b08da2379b857ab.
Report an issue: GitHub.