prestodb/presto · error · IllegalStateException
"Expected entry size to be exactly " + INT128_BYTES + " byte
Error message
"Expected entry size to be exactly " + INT128_BYTES + " bytes but was " + (entryPositionCount * SIZE_OF_LONG)
What it means
Int128ArrayBuilder writes each 128-bit entry as exactly 2 longs (16 bytes) before closeEntry seals it. If entryPositionCount != 2 at closeEntry time, the entry is incomplete (not exactly 16 bytes written), so IllegalStateException is thrown to prevent writing a corrupt value into the block.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/Int128ArrayBlockBuilder.java:89
@Override
public BlockBuilder writeLong(long value)
{
if (valueIsNull.length <= positionCount) {
growCapacity();
}
values[(positionCount * 2) + entryPositionCount] = value;
entryPositionCount++;
hasNonNullValue = true;
return this;
}
@Override
public BlockBuilder closeEntry()
{
if (entryPositionCount != 2) {
throw new IllegalStateException("Expected entry size to be exactly " + INT128_BYTES + " bytes but was " + (entryPositionCount * SIZE_OF_LONG));
}
positionCount++;
entryPositionCount = 0;
if (blockBuilderStatus != null) {
blockBuilderStatus.addBytes(Byte.BYTES + INT128_BYTES);
}
return this;
}
@Override
public BlockBuilder appendNull()
{
if (valueIsNull.length <= positionCount) {
growCapacity();
}
if (entryPositionCount != 0) {
throw new IllegalStateException("Current entry must be closed before a null can be written");View on GitHub (pinned to 55bb57d202)
Solutions
- For each entry write both halves: builder.writeLong(low, 0); builder.writeLong(high, 1); then closeEntry().
- Ensure the writer dispatches by type precision — use Int128ArrayBuilder only for values needing 16 bytes (DECIMAL(38,x)); long decimals use BigintArrayBuilder.
- If an entry was partially written, call resetToCurrentSize/producePage correctly instead of closeEntry; do not call closeEntry twice.
Example fix
// before builder.writeLong(value); // only 8 bytes builder.closeEntry(); // throws // after builder.writeLong(low64, 0); builder.writeLong(high64, 1); builder.closeEntry();
Defensive patterns
Strategy: validation
Validate before calling
// before closing, ensure exactly 16 bytes (2 longs) were written for the entry // Int128ArrayBuilder tracks entryPositionCount internally; write both halves first builder.writeLong(low, 0); builder.writeLong(high, 1); builder.closeEntry();
Type guard
boolean entryFullyWritten(int entryPositionCount) { return entryPositionCount == 2; } // 2 longs = 16 bytes Try / catch
try {
builder.closeEntry();
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Expected entry size to be exactly")) {
throw new IllegalStateException("INT128 entry incomplete: write both 64-bit halves before closeEntry", e);
}
throw e;
} Prevention
- Always pair writeLong(low, 0) with writeLong(high, 1) for INT128 entries.
- Dispatch writers by decimal precision: 16-byte entries only for DECIMAL(p,x) with p > 18.
- Never call closeEntry twice or after an aborted partial write; use the builder's reset/rollback APIs.
When it happens
Trigger: Calling closeEntry() on Int128ArrayBuilder after writing fewer or more than 2 longs — e.g. writing only writeLong(value, 0) without the high part, calling closeEntry twice, or a buildLongs-style loop writing one long per entry for DECIMAL(38,x).
Common situations: Generic BlockBuilder code treating INT128 like BIGINT (one writeLong then closeEntry); reset/abort paths that leave entryPositionCount in a partial state; decimal writers with wrong precision dispatch (writing 1 long for a 38-digit decimal).
Related errors
- Current entry must be closed before a null can be written
- position is not valid
- values length is less than positionCount
- offset must be 0 or 8
- otherOffset %d, length %d are invalid for otherSlice with le
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/72a3a423db1274fe.
Report an issue: GitHub.