{"record":{"id":"677bae918b4b1a80","repo":"prestodb/presto","slug":"expected-entry-to-be-opened-but-was-closed","errorCode":null,"errorMessage":"Expected entry to be opened but was closed","messagePattern":"Expected entry to be opened but was closed","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"presto-common/src/main/java/com/facebook/presto/common/block/RowBlockBuilder.java","lineNumber":183,"sourceCode":"    {\n        if (currentEntryOpened) {\n            throw new IllegalStateException(\"Expected current entry to be closed but was opened\");\n        }\n        currentEntryOpened = true;\n    }\n\n    @Override\n    public SingleRowBlockWriter beginBlockEntry()\n    {\n        beginDirectEntry();\n        return new SingleRowBlockWriter(fieldBlockBuilders[0].getPositionCount(), fieldBlockBuilders);\n    }\n\n    @Override\n    public BlockBuilder closeEntry()\n    {\n        if (!currentEntryOpened) {\n            throw new IllegalStateException(\"Expected entry to be opened but was closed\");\n        }\n\n        entryAdded(false);\n        currentEntryOpened = false;\n        return this;\n    }\n\n    @Override\n    public BlockBuilder appendNull()\n    {\n        if (currentEntryOpened) {\n            throw new IllegalStateException(\"Current entry must be closed before a null can be written\");\n        }\n\n        entryAdded(true);\n        return this;\n    }\n","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-common/src/main/java/com/facebook/presto/common/block/RowBlockBuilder.java#L165-L201","documentation":"RowBlockBuilder.closeEntry finalizes the current row entry and requires that an entry was opened (via beginEntry / entry lifecycle) beforehand. Calling closeEntry without a matching open is a lifecycle misuse, so it throws IllegalStateException. The builder tracks this with currentEntryOpened.","triggerScenarios":"Calling closeEntry() on a RowBlockBuilder with currentEntryOpened == false — e.g. double closeEntry, closeEntry before writing any field, or reusing a builder after a previous entry was closed without opening a new one.","commonSituations":"Custom serializers or aggregation code that manually drives the builder API and mishandles the begin/close pairing, especially across conditional branches or exception paths.","solutions":["Pair every closeEntry() with exactly one preceding beginEntry()","Add a boolean flag in caller code to track entry-open state","Use higher-level helpers (buildFieldChildren / element writers) that manage the lifecycle"],"exampleFix":"// before\nrowBlockBuilder.closeEntry(); // may be called twice on some paths\n// after\nif (rowBlockBuilder != null && entryOpen) {\n    rowBlockBuilder.closeEntry();\n    entryOpen = false;\n}","handlingStrategy":"try-catch","validationCode":"if (!entryOpen) {\n    throw new IllegalStateException(\"closeEntry called without beginEntry\");\n}\nrowBlockBuilder.closeEntry();","typeGuard":null,"tryCatchPattern":"try {\n    rowBlockBuilder.closeEntry();\n} catch (IllegalStateException e) {\n    // correct builder lifecycle management in caller\n}","preventionTips":["Track entry-open state explicitly in caller code","Always pair beginEntry/closeEntry, including on exception paths","Prefer high-level writer helpers over manual lifecycle calls"],"tags":["illegal-state","row-block","builder-lifecycle"],"backgroundTag":"builder-entry-not-open","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}