prestodb/presto · error · IllegalStateException

Current entry must be closed before a null can be written

Error message

Current entry must be closed before a null can be written

What it means

VariableWidthBlockBuilder.builds entries sequentially; an entry is 'open' while values have been written but the entry not yet closed (lengthEntry closed). appendNull cannot represent an open entry, so when currentEntrySize > 0 it throws IllegalStateException, requiring the caller to close the current entry first.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/block/VariableWidthBlockBuilder.java:283

        }
        sliceOutput.writeBytes(source, sourceIndex, length);
        currentEntrySize += length;
        return this;
    }

    @Override
    public BlockBuilder closeEntry()
    {
        entryAdded(currentEntrySize, false);
        currentEntrySize = 0;
        return this;
    }

    @Override
    public BlockBuilder appendNull()
    {
        if (currentEntrySize > 0) {
            throw new IllegalStateException("Current entry must be closed before a null can be written");
        }

        hasNullValue = true;
        entryAdded(0, true);
        return this;
    }

    private void entryAdded(int bytesWritten, boolean isNull)
    {
        if (!initialized) {
            initializeCapacity();
        }
        if (valueIsNull.length <= positions) {
            growCapacity();
        }

        valueIsNull[positions] = isNull;
        offsets[positions + 1] = sliceOutput.size();

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Close the current entry (closeEntry()) before calling appendNull().
  2. If the value must be null, do not write partial bytes; call appendNull instead of writing and abandoning the entry.
  3. On error paths, reset the builder or finish/abandon the row before appending new values.

Example fix

// before
builder.writeBytes(slice, 0, 4);
builder.appendNull(); // throws: entry still open
// after
builder.writeBytes(slice, 0, 4);
builder.closeEntry();
builder.appendNull();
Defensive patterns

Strategy: try-catch

Validate before calling

if (isValueNull) {
    // do not write partial bytes; go straight to appendNull
    builder.appendNull();
} else {
    builder.writeBytes(...).closeEntry();
}

Try / catch

try {
    builder.appendNull();
} catch (IllegalStateException e) {
    // entry still open: close or reset builder before continuing
    builder.closeEntry();
    builder.appendNull();
}

Prevention

When it happens

Trigger: Calling appendNull() after writing partial bytes into the current entry without closing it — i.e. beginEntry/writeBytes without matching closeEntry; seen in callers like readPositionFrom and various tests when a write path forgets to close an entry.

Common situations: Custom serialization code that writes bytes then decides the value is null; exception paths that abandon a half-written entry and continue appending; Parquet/ORC reader code paths writing partial values.

Related errors


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