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

Int128ArrayBlockBuilder builds variable-width 128-bit integer entries via beginEntry/appendNull/closeEntry. A null (appendNull) is itself a complete entry, so calling appendNull while an entry is still open (entryPositionCount != 0) would corrupt the block layout; the builder throws IllegalStateException to force the caller to close the current entry first.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/block/Int128ArrayBlockBuilder.java:107

            throw new IllegalStateException("Expected entry size to be exactly " + INT128_BYTES + " bytes but was " + (entryPositionCount * SIZE_OF_LONG));
        }

        positionCount++;
        entryPositionCount = 0;
        if (blockBuilderStatus != null) {
            blockBuilderStatus.addBytes(Byte.BYTES + INT128_BYTES);
        }
        return this;
    }

    @Override
    public BlockBuilder appendNull()
    {
        if (valueIsNull.length <= positionCount) {
            growCapacity();
        }
        if (entryPositionCount != 0) {
            throw new IllegalStateException("Current entry must be closed before a null can be written");
        }

        valueIsNull[positionCount] = true;

        hasNullValue = true;
        positionCount++;
        if (blockBuilderStatus != null) {
            blockBuilderStatus.addBytes(Byte.BYTES + INT128_BYTES);
        }
        return this;
    }

    @Override
    public Block build()
    {
        if (!hasNonNullValue) {
            return new RunLengthEncodedBlock(NULL_VALUE_BLOCK, positionCount);
        }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Call closeEntry() (or ensure the prior entry was closed) before invoking appendNull().
  2. Restructure copying logic so null positions use appendNull() only when no entry is open, and value positions use beginEntry/writeBytes/closeEntry.
  3. If wrapping this builder, expose appendNull only when the builder is not inside an entry (check entryPositionCount == 0).

Example fix

// before
blockBuilder.beginEntry();
blockBuilder.appendNull(); // IllegalStateException
// after
blockBuilder.beginEntry();
blockBuilder.closeEntry();
blockBuilder.appendNull();
Defensive patterns

Strategy: validation

Validate before calling

if (blockBuilder instanceof Int128ArrayBlockBuilder) {
    // ensure no entry is open before appending a null
    blockBuilder.closeEntry(); // or track entry state in your wrapper
}
blockBuilder.appendNull();

Type guard

boolean canAppendNull(BlockBuilder b) { return b.getPositionCount() == 0 || b instanceof Int128ArrayBlockBuilder; }

Try / catch

try {
    builder.appendNull();
} catch (IllegalStateException e) {
    builder.closeEntry();
    builder.appendNull();
}

Prevention

When it happens

Trigger: Calling appendNull() after beginEntry() and writing partial value bytes without calling closeEntry(), or calling appendNull() directly inside an open entry instead of via writeByte/append structure. Typical call path: readPositionFrom or a block-building loop that begins an entry then switches to appendNull.

Common situations: Hand-rolled block copy/conversion code that mixes beginEntry/appendNull incorrectly; serializers that call appendNull unconditionally without tracking entry state; copying positions between blocks where nulls and values share one code path.

Related errors


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