prestodb/presto · error · IllegalStateException

Invalid field position selection after nulls removed: " + se

Error message

Invalid field position selection after nulls removed: " + selectedFieldPositionCount

What it means

In getPositionsSizeInBytes, AbstractRowBlock subtracts one field position for every selected row that is null. If the count goes negative, the selected positions do not correspond to valid row positions in this block, so the library throws IllegalStateException to signal a corrupted/inconsistent selection set.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/block/AbstractRowBlock.java:233

        if (selectedRowPositions == positionCount) {
            return getSizeInBytes();
        }

        OptionalInt fixedSizePerFieldPosition = fixedSizeInBytesForAllFieldsPerPosition();
        if (fixedSizePerFieldPosition.isPresent()) {
            // All field blocks are fixed size per position, no specific position mapping is necessary
            int selectedFieldPositionCount = selectedRowPositions;
            boolean[] rowIsNull = getRowIsNull();
            if (rowIsNull != null) {
                // Some positions in usedPositions may be null which must be removed from the selectedFieldPositionCount
                int offsetBase = getOffsetBase();
                for (int i = 0; i < positions.length; i++) {
                    if (positions[i] && rowIsNull[i + offsetBase]) {
                        selectedFieldPositionCount--; // selected row is null, don't include it in the selected field positions
                    }
                }
                if (selectedFieldPositionCount < 0) {
                    throw new IllegalStateException("Invalid field position selection after nulls removed: " + selectedFieldPositionCount);
                }
            }
            return ((Integer.BYTES + Byte.BYTES) * (long) selectedRowPositions) + (fixedSizePerFieldPosition.getAsInt() * (long) selectedFieldPositionCount);
        }

        return getSpecificPositionsSizeInBytes(positions, selectedRowPositions);
    }

    private long getSpecificPositionsSizeInBytes(boolean[] positions, int selectedRowPositions)
    {
        int positionCount = getPositionCount();
        int offsetBase = getOffsetBase();
        boolean[] rowIsNull = getRowIsNull();
        // No fixed width size per row, specific positions used must be tracked
        int totalFieldPositions = getRawFieldBlocks()[0].getPositionCount();
        boolean[] fieldPositions;
        int selectedFieldPositionCount;
        if (rowIsNull == null) {

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Ensure the positions boolean array was computed for this exact block and matches its position count.
  2. Recompute the selection from the block's own positions rather than reusing masks across blocks.
  3. Check whether the caller applied selection logic before or after filtering nulls inconsistently; unify on the block's rowIsNull.
Defensive patterns

Strategy: validation

Validate before calling

checkArgument(positions.length == rowBlock.getPositionCount(),
    "selection mask length %s does not match block position count %s",
    positions.length, rowBlock.getPositionCount());

Try / catch

try {
    long size = rowBlock.getPositionsSizeInBytes(positions, selectedPositions);
} catch (IllegalStateException e) {
    if (e.getMessage() != null && e.getMessage().contains("Invalid field position selection")) {
        // recompute selection for this block
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling getPositionsSizeInBytes with a positions selection array whose length or indexing does not match the block's positions, or a selection computed against a different block.

Common situations: Custom operators or page-repartitioning code passing selection masks built for another block; bugs in compaction code that mixes position selections across blocks.

Related errors


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