prestodb/presto · error · IllegalStateException
Current entry must be closed before a null can be written
Error message
Current entry must be closed before a null can be written
What it means
Int128ArrayBlockBuilder builds variable-width 128-bit integer entries via beginEntry/appendNull/closeEntry. A null (appendNull) is itself a complete entry, so calling appendNull while an entry is still open (entryPositionCount != 0) would corrupt the block layout; the builder throws IllegalStateException to force the caller to close the current entry first.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/Int128ArrayBlockBuilder.java:107
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");
}
valueIsNull[positionCount] = true;
hasNullValue = true;
positionCount++;
if (blockBuilderStatus != null) {
blockBuilderStatus.addBytes(Byte.BYTES + INT128_BYTES);
}
return this;
}
@Override
public Block build()
{
if (!hasNonNullValue) {
return new RunLengthEncodedBlock(NULL_VALUE_BLOCK, positionCount);
}View on GitHub (pinned to 55bb57d202)
Solutions
- Call closeEntry() (or ensure the prior entry was closed) before invoking appendNull().
- Restructure copying logic so null positions use appendNull() only when no entry is open, and value positions use beginEntry/writeBytes/closeEntry.
- If wrapping this builder, expose appendNull only when the builder is not inside an entry (check entryPositionCount == 0).
Example fix
// before blockBuilder.beginEntry(); blockBuilder.appendNull(); // IllegalStateException // after blockBuilder.beginEntry(); blockBuilder.closeEntry(); blockBuilder.appendNull();
Defensive patterns
Strategy: validation
Validate before calling
if (blockBuilder instanceof Int128ArrayBlockBuilder) {
// ensure no entry is open before appending a null
blockBuilder.closeEntry(); // or track entry state in your wrapper
}
blockBuilder.appendNull(); Type guard
boolean canAppendNull(BlockBuilder b) { return b.getPositionCount() == 0 || b instanceof Int128ArrayBlockBuilder; } Try / catch
try {
builder.appendNull();
} catch (IllegalStateException e) {
builder.closeEntry();
builder.appendNull();
} Prevention
- Never interleave beginEntry/write with appendNull; treat nulls as standalone entries
- Centralize block copying in one utility that tracks entry state
- Prefer writeNull-style APIs on higher-level writers when available
When it happens
Trigger: Calling appendNull() after beginEntry() and writing partial value bytes without calling closeEntry(), or calling appendNull() directly inside an open entry instead of via writeByte/append structure. Typical call path: readPositionFrom or a block-building loop that begins an entry then switches to appendNull.
Common situations: Hand-rolled block copy/conversion code that mixes beginEntry/appendNull incorrectly; serializers that call appendNull unconditionally without tracking entry state; copying positions between blocks where nulls and values share one code path.
Related errors
- "Expected entry size to be exactly " + INT128_BYTES + " byte
- Current entry must be closed before a null can be written
- Current entry must be closed before the block can be built
- field block builder can only be obtained before any sequenti
- field block builder has been returned
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/a01ceddfa5355cc5.
Report an issue: GitHub.