prestodb/presto · error · IllegalStateException
Expected current entry to be closed but was opened
Error message
Expected current entry to be closed but was opened
What it means
appendStructure requires that no entry is currently open: it sets currentEntryOpened = true itself after validating. Calling it while a previous beginBlockEntry()/appendStructure entry is still open would nest entries and desynchronize field offsets, so the library throws IllegalStateException.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/RowBlockBuilder.java:273
fieldBlocks[i] = fieldBlockBuilders[i].build();
}
return createRowBlockInternal(0, positionCount, hasNullRow ? rowIsNull : null, fieldBlockOffsets, fieldBlocks);
}
@Override
public String toString()
{
return format("RowBlockBuilder(%d){numFields=%d, positionCount=%d", hashCode(), numFields, getPositionCount());
}
@Override
public BlockBuilder appendStructure(Block block)
{
if (!(block instanceof AbstractSingleRowBlock)) {
throw new IllegalStateException("Expected AbstractSingleRowBlock");
}
if (currentEntryOpened) {
throw new IllegalStateException("Expected current entry to be closed but was opened");
}
currentEntryOpened = true;
int blockPositionCount = block.getPositionCount();
if (blockPositionCount != numFields) {
throw new IllegalArgumentException(format("block position count (%s) is not equal to number of fields (%s)", blockPositionCount, numFields));
}
for (int i = 0; i < blockPositionCount; i++) {
if (block.isNull(i)) {
fieldBlockBuilders[i].appendNull();
}
else {
block.writePositionTo(i, fieldBlockBuilders[i]);
}
}
closeEntry();
return this;View on GitHub (pinned to 55bb57d202)
Solutions
- Call closeEntry() after each appendStructure() before the next append
- Restructure copy loops: appendStructure(block); rowBuilder.closeEntry();
- Use try/finally around the copy loop body
- Never mix beginBlockEntry-based writes with appendStructure for the same row
Example fix
// before
for (int i = 0; i < block.getPositionCount(); i++) {
rowBuilder.appendStructure(block.getBlock(i)); // second call throws: entry still open
}
// after
for (int i = 0; i < block.getPositionCount(); i++) {
rowBuilder.appendStructure(block.getBlock(i));
rowBuilder.closeEntry();
} Defensive patterns
Strategy: validation
Validate before calling
// maintain open-entry state around appendStructure usage
boolean safeAppendStructure(RowBlockBuilder b, Block row) {
// appendStructure must not be called while another entry is open;
// ensure your wrapper never leaves an entry open:
b.appendStructure(row);
b.closeEntry(); // immediately close what appendStructure opened
return true;
}
Try / catch
try {
rowBuilder.appendStructure(block);
rowBuilder.closeEntry();
} catch (IllegalStateException e) {
if (e.getMessage().contains("Expected current entry to be closed")) {
throw new IllegalStateException("nested appendStructure: previous entry not closed", e);
}
throw e;
} Prevention
- Treat appendStructure as begin+open: always follow with closeEntry()
- Never interleave beginBlockEntry and appendStructure for the same row
- In copy loops, close the entry inside the loop body
- Wrap the loop in try/finally
When it happens
Trigger: Calling appendStructure() after beginBlockEntry() without closeEntry(), or calling appendStructure() twice in a row without closing the entry opened by the first call.
Common situations: Bulk-copy loops copying row blocks that call appendStructure per position but forget that it auto-opens and requires closeEntry after each position; exception paths between appendStructure and closeEntry.
Related errors
- Invalid field position selection after nulls removed: " + se
- Current entry must be closed before a null can be written
- Current entry must be closed before the block can be built
- Expected AbstractSingleRowBlock
- path is empty
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/5bf53438c72dfb4b.
Report an issue: GitHub.