{"record":{"id":"eefb4ff3e66b4bb6","repo":"prestodb/presto","slug":"current-entry-must-be-closed-before-a-null-can-be-eefb4f","errorCode":null,"errorMessage":"Current entry must be closed before a null can be written","messagePattern":"Current entry must be closed before a null can be written","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"presto-common/src/main/java/com/facebook/presto/common/block/RowBlockBuilder.java","lineNumber":195,"sourceCode":"    }\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\n    @Override\n    public BlockBuilder readPositionFrom(SliceInput input)\n    {\n        boolean isNull = input.readByte() == 0;\n        if (isNull) {\n            appendNull();\n        }\n        else {\n            for (BlockBuilder blockBuilder : fieldBlockBuilders) {\n                blockBuilder.readPositionFrom(input);\n            }\n            entryAdded(false);","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-common/src/main/java/com/facebook/presto/common/block/RowBlockBuilder.java#L177-L213","documentation":"RowBlockBuilder.appendNull() adds a NULL row to the row block being built. Row entries are transactional: between beginBlockEntry() and closeEntry() the builder considers an entry 'open'. The library throws this IllegalStateException because writing a null while a nested row entry is still open would corrupt the row's field offset bookkeeping.","triggerScenarios":"Calling appendNull() after beginBlockEntry() without first calling closeEntry() on the row builder; also any code path (e.g. readPositionFrom or a type's read method) that appends a null while an entry opened via appendStructure/beginBlockEntry remains open.","commonSituations":"Custom ParametricType/BlockEncoding implementations or deserializers that begin an entry but take an early return (e.g. on a null field) before closing it; test code building nested row types that forget closeEntry() in a branch.","solutions":["Ensure every beginBlockEntry() is matched by closeEntry() before calling appendNull()","Use try/finally around entry building so closeEntry() runs on all paths","Restructure code to decide null-vs-value before opening the entry","If value-vs-null is decided inside the entry, close the current entry and then call appendNull()"],"exampleFix":"// before\nbuilder.beginBlockEntry();\nif (isNull) {\n    builder.appendNull(); // IllegalStateException: entry still open\n}\n// after\nif (isNull) {\n    builder.appendNull();\n} else {\n    BlockBuilder entry = builder.beginBlockEntry();\n    // write fields...\n    builder.closeEntry();\n}","handlingStrategy":"validation","validationCode":"// before appending null to a RowBlockBuilder\nif (rowBuilder instanceof RowBlockBuilder) {\n    // cannot inspect private currentEntryOpened; instead structure code so appendNull\n    // is only called when no entry is open:\n    //   - decide null vs value before beginBlockEntry()\n    //   - closeEntry() in a finally block\n}\n","typeGuard":null,"tryCatchPattern":"try {\n    rowBuilder.appendNull();\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"Current entry must be closed\")) {\n        // recover: a prior entry was left open; discard builder or track open state yourself\n        throw new IllegalStateException(\"row builder misused: entry left open before appendNull\", e);\n    }\n    throw e;\n}","preventionTips":["Decide null-vs-value before opening a block entry","Pair beginBlockEntry()/closeEntry() with try/finally","Never return or throw from inside an open entry without closing it","Wrap appendStructure calls with an immediate closeEntry()"],"tags":["presto","block-builder","illegal-state","row-block"],"backgroundTag":"block-entry-still-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"}