{"record":{"id":"49034453e96acff2","repo":"prestodb/presto","slug":"field-block-builder-can-only-be-obtained-before-an","errorCode":null,"errorMessage":"field block builder can only be obtained before any sequential write has done","messagePattern":"field block builder can only be obtained before any sequential write has done","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"presto-common/src/main/java/com/facebook/presto/common/block/SingleRowBlockWriter.java","lineNumber":55,"sourceCode":"    SingleRowBlockWriter(int rowIndex, BlockBuilder[] fieldBlockBuilders)\n    {\n        super(rowIndex);\n        this.fieldBlockBuilders = fieldBlockBuilders;\n    }\n\n    /**\n     * Obtains the field {@code BlockBuilder}.\n     * <p>\n     * This method is used to perform random write to {@code SingleRowBlockWriter}.\n     * Each field {@code BlockBuilder} must be written EXACTLY once.\n     * <p>\n     * Field {@code BlockBuilder} can only be obtained before any sequential write has done.\n     * Once obtained, sequential write is no longer allowed.\n     */\n    public BlockBuilder getFieldBlockBuilder(int fieldIndex)\n    {\n        if (currentFieldIndexToWrite != 0) {\n            throw new IllegalStateException(\"field block builder can only be obtained before any sequential write has done\");\n        }\n        fieldBlockBuilderReturned = true;\n        return fieldBlockBuilders[fieldIndex];\n    }\n\n    @Override\n    protected Block getRawFieldBlock(int fieldIndex)\n    {\n        return fieldBlockBuilders[fieldIndex];\n    }\n\n    @Override\n    public long getSizeInBytes()\n    {\n        long size = 0;\n        if (rowIndex == 0) {\n            for (BlockBuilder blockBuilder : fieldBlockBuilders) {\n                size += blockBuilder.getSizeInBytes();","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-common/src/main/java/com/facebook/presto/common/block/SingleRowBlockWriter.java#L37-L73","documentation":"SingleRowBlockWriter supports two mutually exclusive write modes: sequential writes (writeLong/appendStructure) or per-field block builders obtained via getFieldBlockBuilder. This library throws IllegalStateException when getFieldBlockBuilder is called after any sequential write has already started, because the writer's internal position (currentFieldIndexToWrite) has advanced and mixing modes would corrupt the row layout.","triggerScenarios":"Calling getFieldBlockBuilder(fieldIndex) on a SingleRowBlockWriter after at least one sequential write (writeByte, writeShort, writeInt, writeLong, writeBytes, appendStructure) has been performed on the same row; currentFieldIndexToWrite != 0 at call time.","commonSituations":"Serializers that build a row block partly with appendStructure and then try to grab individual field builders for complex types; refactored encoder code where a scalar field write was added before the nested-structure path.","solutions":["Obtain all field block builders via getFieldBlockBuilder BEFORE any sequential write on the row writer.","Restructure the serializer to use one mode exclusively per row: either all fields via field builders, or all via sequential writes.","If both modes are needed, finish the current row, build it, and start a new SingleRowBlockWriter for the next row."],"exampleFix":"// before\nwriter.writeLong(0, value);\nBlockBuilder field = writer.getFieldBlockBuilder(1); // throws\n// after\nBlockBuilder field = writer.getFieldBlockBuilder(1);\nfield.writeLong(value); // use field builders consistently","handlingStrategy":"validation","validationCode":"if (writer.getCurrentFieldIndexToWrite() != 0 /* or track writes yourself */) {\n    throw new IllegalStateException(\"must call getFieldBlockBuilder before any sequential write\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    BlockBuilder f = writer.getFieldBlockBuilder(idx);\n} catch (IllegalStateException e) {\n    // writer already in sequential mode: rebuild the row writer\n}","preventionTips":["Pick one write mode (sequential vs field builders) per row writer up front","Call getFieldBlockBuilder for all needed fields as the first statements","Centralize row-writing in a helper that enforces mode discipline"],"tags":["presto","block-builder","illegal-state","api-misuse"],"backgroundTag":"block-builder-write-mode-conflict","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"}