prestodb/presto · error · IllegalStateException
was used before initialization
Error message
was used before initialization
What it means
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.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/VariableWidthBlockBuilder.java:321
positions++;
if (blockBuilderStatus != null) {
blockBuilderStatus.addBytes(SIZE_OF_BYTE + SIZE_OF_INT + bytesWritten);
}
}
private void growCapacity()
{
int newSize = BlockUtil.calculateNewArraySize(valueIsNull.length);
valueIsNull = Arrays.copyOf(valueIsNull, newSize);
offsets = Arrays.copyOf(offsets, newSize + 1);
updateArraysDataSize();
}
private void initializeCapacity()
{
if (positions != 0 || currentEntrySize != 0) {
throw new IllegalStateException(getClass().getSimpleName() + " was used before initialization");
}
initialized = true;
valueIsNull = new boolean[initialEntryCount];
offsets = new int[initialEntryCount + 1];
sliceOutput = new DynamicSliceOutput(initialSliceOutputSize);
updateArraysDataSize();
}
private void updateArraysDataSize()
{
arraysRetainedSizeInBytes = sizeOf(valueIsNull) + sizeOf(offsets);
}
@Override
public BlockBuilder readPositionFrom(SliceInput input)
{
boolean isNull = input.readByte() == 0;
if (isNull) {View on GitHub (pinned to 55bb57d202)
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
Example fix
// before builder.writeBytes(slice, 0, len); // builder still holds an open entry from previous use // after builder.reset(); // only when positions == 0 && currentEntrySize == 0 builder.writeBytes(slice, 0, len);
Defensive patterns
Strategy: validation
Validate before calling
if (builder.getPositions() != 0 || /* currentEntrySize not observable; assume dirty */ false) {
builder = new VariableWidthBlockBuilder(null, expectedEntries, expectedBytes);
} Type guard
boolean isReusable(VariableWidthBlockBuilder b) { return b.getPositions() == 0; } Try / catch
try { builder.writeBytes(slice, offset, length); } catch (IllegalStateException e) { builder = new VariableWidthBlockBuilder(null, initialEntryCount, initialSize); builder.writeBytes(slice, offset, length); } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Current entry must be closed before a null can be written
- Current entry must be closed before a null can be written
- Current entry must be closed before the block can be built
- field block builder can only be obtained before any sequenti
- field block builder has been returned
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/738f1f77d38b79ae.
Report an issue: GitHub.