prestodb/presto · error · IllegalArgumentException
position is not valid
Error message
position is not valid
What it means
ByteArrayBlockBuilder.checkReadablePosition throws IllegalArgumentException when a position argument is negative or >= getPositionCount() of the builder's currently built region. It guards the same read APIs as ByteArrayBlock (getByte, isNull, writePositionTo, getSingleValueBlock, copyPositions) while the values still live in the builder.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/ByteArrayBlockBuilder.java:328
return new ByteArrayBlock(0, length, newValueIsNull, newValues);
}
@Override
public String getEncodingName()
{
return ByteArrayBlockEncoding.NAME;
}
@Override
public String toString()
{
return format("ByteArrayBlockBuilder(%d){positionCount=%d}", hashCode(), getPositionCount());
}
private void checkReadablePosition(int position)
{
if (position < 0 || position >= getPositionCount()) {
throw new IllegalArgumentException("position is not valid");
}
}
@Override
public boolean isNullUnchecked(int internalPosition)
{
assert mayHaveNull() : "no nulls present";
assert internalPositionInRange(internalPosition, getOffsetBase(), getPositionCount());
return valueIsNull[internalPosition];
}
@Override
public byte getByteUnchecked(int internalPosition)
{
assert internalPositionInRange(internalPosition, getOffsetBase(), getPositionCount());
return values[internalPosition];
}
View on GitHub (pinned to 55bb57d202)
Solutions
- Call builder.getPositionCount() and bound all reads to it, reading positions 0..positionCount-1
- Ensure closeEntry() is invoked after writing each value so appended values become readable positions
- Use build() to convert to a Block before random-position reads if the region semantics are unclear
- Validate incoming position arrays before calling copyPositions on a builder
Example fix
// before builder.writeByte(7); int v = builder.getByte(builder.getPositionCount()); // throws // after builder.writeByte(7); builder.closeEntry(); int v = builder.getByte(builder.getPositionCount() - 1);
Defensive patterns
Strategy: validation
Validate before calling
int count = builder.getPositionCount();
if (position < 0 || position >= count) {
throw new IllegalArgumentException("position " + position + " out of range [0, " + count + ")");
}
byte v = builder.getByte(position);
Type guard
boolean builderHasPosition(ByteArrayBlockBuilder builder, int position) {
return position >= 0 && position < builder.getPositionCount();
}
Try / catch
try {
byte v = builder.getByte(position);
} catch (IllegalArgumentException e) {
throw new IllegalStateException("builder position out of range; call closeEntry()/build() before reading", e);
}
Prevention
- Call closeEntry() after each value write so appended values count as readable positions
- Bound reads with builder.getPositionCount() fetched immediately before the read
- Prefer builder.build() for random-position reads
When it happens
Trigger: Reading from a ByteArrayBlockBuilder with position >= getPositionCount(), e.g. calling getByte(positionCount) before build() flushes the last value; forgetting that appended-but-not-finished values may not count; using positions from a differently sized block; negative positions from unvalidated input.
Common situations: Custom aggregation/accumulator code reading builder positions before closing the entry (missing builder.closeEntry()); copying data between blocks whose position counts differ; testing code assuming unread appended values are immediately visible.
Related errors
- position is not valid
- position is not valid
- position is not valid
- position is not valid: " + position
- position is not valid: " + position
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/dbe13954f2c239b3.
Report an issue: GitHub.