{"record":{"id":"738f1f77d38b79ae","repo":"prestodb/presto","slug":"was-used-before-initialization","errorCode":null,"errorMessage":" was used before initialization","messagePattern":" was used before initialization","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"presto-common/src/main/java/com/facebook/presto/common/block/VariableWidthBlockBuilder.java","lineNumber":321,"sourceCode":"        positions++;\n\n        if (blockBuilderStatus != null) {\n            blockBuilderStatus.addBytes(SIZE_OF_BYTE + SIZE_OF_INT + bytesWritten);\n        }\n    }\n\n    private void growCapacity()\n    {\n        int newSize = BlockUtil.calculateNewArraySize(valueIsNull.length);\n        valueIsNull = Arrays.copyOf(valueIsNull, newSize);\n        offsets = Arrays.copyOf(offsets, newSize + 1);\n        updateArraysDataSize();\n    }\n\n    private void initializeCapacity()\n    {\n        if (positions != 0 || currentEntrySize != 0) {\n            throw new IllegalStateException(getClass().getSimpleName() + \" was used before initialization\");\n        }\n        initialized = true;\n        valueIsNull = new boolean[initialEntryCount];\n        offsets = new int[initialEntryCount + 1];\n        sliceOutput = new DynamicSliceOutput(initialSliceOutputSize);\n        updateArraysDataSize();\n    }\n\n    private void updateArraysDataSize()\n    {\n        arraysRetainedSizeInBytes = sizeOf(valueIsNull) + sizeOf(offsets);\n    }\n\n    @Override\n    public BlockBuilder readPositionFrom(SliceInput input)\n    {\n        boolean isNull = input.readByte() == 0;\n        if (isNull) {","sourceCodeStart":303,"sourceCodeEnd":339,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-common/src/main/java/com/facebook/presto/common/block/VariableWidthBlockBuilder.java#L303-L339","documentation":"VariableWidthBlockBuilder lazily allocates its internal arrays (valueIsNull, offsets, sliceOutput) in initializeCapacity. This IllegalStateException is thrown when the builder still has buffered state (positions or currentEntrySize non-zero) but initializeCapacity is called again, indicating the builder was used without being properly reset/re-initialized after prior writes.","triggerScenarios":"Calling a write method (writeByte, writeShort, writeInt, writeLong, writeBytes) or entryAdded on a builder whose internal state was already partially advanced (positions != 0 or currentEntrySize != 0), e.g. reusing a builder after writes without reset(), or a lifecycle bug where entryEnded/closeEntry was never called so state remains dirty.","commonSituations":"Reusing a pooled/cached BlockBuilder across queries without reset(); calling reset() when an entry write is still open (currentEntrySize > 0); custom code that copies builder state and calls initializeCapacity directly via reflection or subclassing.","solutions":["Call reset() only after the current entry is closed (entryEnded), or create a new VariableWidthBlockBuilder instead of reusing one","Ensure each write sequence is completed with closeEntry()/entryEnded before further lifecycle calls","If pooling builders, reset them at the start of each use and verify positions==0 and currentEntrySize==0","Check for double initialization paths in custom block builder subclasses"],"exampleFix":"// before\nbuilder.writeBytes(slice, 0, len); // builder still holds an open entry from previous use\n// after\nbuilder.reset(); // only when positions == 0 && currentEntrySize == 0\nbuilder.writeBytes(slice, 0, len);","handlingStrategy":"validation","validationCode":"if (builder.getPositions() != 0 || /* currentEntrySize not observable; assume dirty */ false) {\n    builder = new VariableWidthBlockBuilder(null, expectedEntries, expectedBytes);\n}","typeGuard":"boolean isReusable(VariableWidthBlockBuilder b) { return b.getPositions() == 0; }","tryCatchPattern":"try { builder.writeBytes(slice, offset, length); } catch (IllegalStateException e) { builder = new VariableWidthBlockBuilder(null, initialEntryCount, initialSize); builder.writeBytes(slice, offset, length); }","preventionTips":["Always pair writes with closeEntry before any lifecycle call","Create fresh builders per block instead of reusing pooled ones unless reset is guaranteed safe","Wrap multi-step build sequences in try/finally that discards the builder on failure"],"tags":["block-builder","state-management","illegal-state"],"backgroundTag":"illegal-state-object-not-initialized","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"}