{"record":{"id":"cc8cb65c5ad3d732","repo":"prestodb/presto","slug":"cannot-do-sequential-write-after-getfieldblockbuil","errorCode":null,"errorMessage":"cannot do sequential write after getFieldBlockBuilder is called","messagePattern":"cannot do sequential write after getFieldBlockBuilder is called","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"presto-common/src/main/java/com/facebook/presto/common/block/SingleRowBlockWriter.java","lineNumber":263,"sourceCode":"    {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public String toString()\n    {\n        if (!fieldBlockBuilderReturned) {\n            return format(\"SingleRowBlockWriter(%d){numFields=%d, fieldBlockBuilderReturned=false, positionCount=%d}\", hashCode(), fieldBlockBuilders.length, getPositionCount());\n        }\n        else {\n            return format(\"SingleRowBlockWriter(%d){numFields=%d, fieldBlockBuilderReturned=true}\", hashCode(), fieldBlockBuilders.length);\n        }\n    }\n\n    private void checkFieldIndexToWrite()\n    {\n        if (fieldBlockBuilderReturned) {\n            throw new IllegalStateException(\"cannot do sequential write after getFieldBlockBuilder is called\");\n        }\n        if (currentFieldIndexToWrite >= fieldBlockBuilders.length) {\n            throw new IllegalStateException(\"currentFieldIndexToWrite is not valid\");\n        }\n    }\n}\n","sourceCodeStart":245,"sourceCodeEnd":270,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-common/src/main/java/com/facebook/presto/common/block/SingleRowBlockWriter.java#L245-L270","documentation":"checkFieldIndexToWrite enforces the reverse rule of error 410: after getFieldBlockBuilder hands out a field block builder, sequential writes are forbidden. Any sequential write method (writeByte, writeShort, writeInt, writeLong, writeBytes, appendStructure) throws IllegalStateException because mixing modes would corrupt field offsets.","triggerScenarios":"Calling writeByte/writeShort/writeInt/writeLong/writeBytes/appendStructure on a SingleRowBlockWriter after getFieldBlockBuilder() has been called on that writer instance.","commonSituations":"Type serializers that take the field-builder path for one field but fall back to sequential writes for another field within the same row; generic serialization code that checks types at runtime and mixes both APIs.","solutions":["Write every field through the obtained field block builders once getFieldBlockBuilder has been used.","Choose exactly one write mode per row writer before serializing.","Reset by completing the current row and creating a new SingleRowBlockWriter."],"exampleFix":"// before\nBlockBuilder f = writer.getFieldBlockBuilder(0);\nwriter.writeLong(1, value); // throws\n// after\nBlockBuilder f = writer.getFieldBlockBuilder(0);\nBlockBuilder f1 = writer.getFieldBlockBuilder(1);\nf1.writeLong(value);","handlingStrategy":"validation","validationCode":"checkState(!fieldBuildersObtained, \"use field builders for all writes once obtained\");","typeGuard":null,"tryCatchPattern":"try {\n    writer.writeLong(idx, value);\n} catch (IllegalStateException e) {\n    // sequential write after getFieldBlockBuilder: route through field builder\n}","preventionTips":["Route all field writes through field block builders once getFieldBlockBuilder is used","Encode the chosen write mode in the serializer's type dispatch so it cannot mix","Add unit tests covering every field type path in the row encoder"],"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"}