prestodb/presto · error · IllegalStateException
field block builder can only be obtained before any sequenti
Error message
field block builder can only be obtained before any sequential write has done
What it means
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.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/SingleRowBlockWriter.java:55
SingleRowBlockWriter(int rowIndex, BlockBuilder[] fieldBlockBuilders)
{
super(rowIndex);
this.fieldBlockBuilders = fieldBlockBuilders;
}
/**
* Obtains the field {@code BlockBuilder}.
* <p>
* This method is used to perform random write to {@code SingleRowBlockWriter}.
* Each field {@code BlockBuilder} must be written EXACTLY once.
* <p>
* Field {@code BlockBuilder} can only be obtained before any sequential write has done.
* Once obtained, sequential write is no longer allowed.
*/
public BlockBuilder getFieldBlockBuilder(int fieldIndex)
{
if (currentFieldIndexToWrite != 0) {
throw new IllegalStateException("field block builder can only be obtained before any sequential write has done");
}
fieldBlockBuilderReturned = true;
return fieldBlockBuilders[fieldIndex];
}
@Override
protected Block getRawFieldBlock(int fieldIndex)
{
return fieldBlockBuilders[fieldIndex];
}
@Override
public long getSizeInBytes()
{
long size = 0;
if (rowIndex == 0) {
for (BlockBuilder blockBuilder : fieldBlockBuilders) {
size += blockBuilder.getSizeInBytes();View on GitHub (pinned to 55bb57d202)
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.
Example fix
// before writer.writeLong(0, value); BlockBuilder field = writer.getFieldBlockBuilder(1); // throws // after BlockBuilder field = writer.getFieldBlockBuilder(1); field.writeLong(value); // use field builders consistently
Defensive patterns
Strategy: validation
Validate before calling
if (writer.getCurrentFieldIndexToWrite() != 0 /* or track writes yourself */) {
throw new IllegalStateException("must call getFieldBlockBuilder before any sequential write");
} Try / catch
try {
BlockBuilder f = writer.getFieldBlockBuilder(idx);
} catch (IllegalStateException e) {
// writer already in sequential mode: rebuild the row writer
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- cannot do sequential write after getFieldBlockBuilder is cal
- 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 has been returned
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/49034453e96acff2.
Report an issue: GitHub.