prestodb/presto · error · IllegalStateException

field block builder has been returned

Error message

field block builder has been returned

What it means

SingleRowBlockWriter.getPositionCount returns the number of sequential entries written so far. Once getFieldBlockBuilder has been called the writer switches to field-builder mode, so the sequential position count is meaningless; the library throws IllegalStateException instead of returning a misleading value.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/block/SingleRowBlockWriter.java:220

        else {
            checkFieldIndexToWrite();
            fieldBlockBuilders[currentFieldIndexToWrite].readPositionFrom(input);
            entryAdded();
        }
        return this;
    }

    private void entryAdded()
    {
        isEntryOpen = false;
        currentFieldIndexToWrite++;
    }

    @Override
    public int getPositionCount()
    {
        if (fieldBlockBuilderReturned) {
            throw new IllegalStateException("field block builder has been returned");
        }
        return currentFieldIndexToWrite;
    }

    @Override
    public String getEncodingName()
    {
        throw new UnsupportedOperationException();
    }

    @Override
    public Block build()
    {
        throw new UnsupportedOperationException();
    }

    @Override
    public BlockBuilder newBlockBuilderLike(BlockBuilderStatus blockBuilderStatus)

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Do not call getPositionCount (including via toString/logging) after getFieldBlockBuilder has been called.
  2. Track write progress yourself in caller code when in field-builder mode.
  3. Call getPositionCount before obtaining any field block builder, or after the row is fully built via a fresh writer.

Example fix

// before
BlockBuilder f = writer.getFieldBlockBuilder(0);
LOG.debug("state: " + writer); // toString -> getPositionCount -> throws
// after
LOG.debug("positions: " + writer.getPositionCount()); // before getFieldBlockBuilder
BlockBuilder f = writer.getFieldBlockBuilder(0);
Defensive patterns

Strategy: try-catch

Validate before calling

if (fieldBlockBuilderReturned) { /* do not call getPositionCount; track progress in caller */ }

Try / catch

try {
    int n = writer.getPositionCount();
} catch (IllegalStateException e) {
    // writer switched to field-builder mode; use caller-side counters
}

Prevention

When it happens

Trigger: Calling getPositionCount() on a SingleRowBlockWriter after getFieldBlockBuilder() was invoked (fieldBlockBuilderReturned == true). Notably the auto-generated toString() implementation calls getPositionCount, so even debugging/logging the writer after switching modes triggers this.

Common situations: Developers logging the writer (toString) for debugging after obtaining a field block builder; code paths that inspect progress via getPositionCount in mixed-mode serializers.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/cfe7a55ee26b5d2b. Report an issue: GitHub.