prestodb/presto · error · IllegalArgumentException
position is not valid
Error message
position is not valid
What it means
ShortArrayBlockBuilder.checkReadablePosition validates positions before reads (getByte, isNull, writePositionTo, getSingleValueBlock, copyPositions). Positions must satisfy 0 <= position < positionCount (built entries so far). Out-of-range positions throw IllegalArgumentException("position is not valid").
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/ShortArrayBlockBuilder.java:328
return new ShortArrayBlock(0, length, newValueIsNull, newValues);
}
@Override
public String getEncodingName()
{
return ShortArrayBlockEncoding.NAME;
}
@Override
public String toString()
{
return format("ShortArrayBlockBuilder(%d){positionCount=%d}", hashCode(), getPositionCount());
}
private void checkReadablePosition(int position)
{
if (position < 0 || position >= getPositionCount()) {
throw new IllegalArgumentException("position is not valid");
}
}
@Override
public short getShortUnchecked(int internalPosition)
{
assert internalPositionInRange(internalPosition, getOffsetBase(), getPositionCount());
return values[internalPosition];
}
@Override
public boolean isNullUnchecked(int internalPosition)
{
assert mayHaveNull() : "no nulls present";
assert internalPositionInRange(internalPosition, getOffsetBase(), getPositionCount());
return valueIsNull[internalPosition];
}
View on GitHub (pinned to 55bb57d202)
Solutions
- Verify builder.getPositionCount() > position before reading.
- After reset()/newInstance, do not reuse old indices; re-read entries only up to the new positionCount.
- Ensure the builder was fully populated (close/advance entry) before reading its values.
Example fix
// before
builder.reset();
short v = builder.getShort(0, 0); // throws: positionCount is 0
// after
builder.reset();
if (builder.getPositionCount() > 0) {
short v = builder.getShort(0, 0);
} Defensive patterns
Strategy: validation
Validate before calling
if (position < 0 || position >= builder.getPositionCount()) {
throw new IllegalArgumentException("position " + position + " not yet written to builder (count=" + builder.getPositionCount() + ")");
} Type guard
boolean builderHasPosition(BlockBuilder builder, int position) {
return position >= 0 && position < builder.getPositionCount();
} Try / catch
try {
value = builder.getShort(position, 0);
} catch (IllegalArgumentException e) {
if (e.getMessage().equals("position is not valid")) {
log.warn("read at %d but builder has %d entries", position, builder.getPositionCount());
return null;
}
throw e;
} Prevention
- Do not reuse position indices after builder.reset() or newInstance().
- Finish each entry (closeEntry/beginBlock) before reading it back.
- Track built-entry count separately and assert reads stay below it.
When it happens
Trigger: Reading from a ShortArrayBlockBuilder before it has enough entries, or with a negative index; e.g. calling getPositionCount()-dependent accessors with stale index after builder.reset().
Common situations: Reading a builder that was just reset (positionCount = 0), reading position positionCount-1 + 1 in a loop, mixing up builder entry count with expected row count, off-by-one in composite-type field access (getByte with wrong field offset confusion).
Related errors
- position is not valid
- position is not valid
- position is not valid
- position is not valid
- position is not valid
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/1dc9aa92d10998c0.
Report an issue: GitHub.