prestodb/presto · error · java.lang.IllegalArgumentException

Block does not have same position count

Error message

Block does not have same position count

What it means

Page.appendColumn(block) adds a column to an existing page; it throws IllegalArgumentException when the new block's position count differs from the page's positionCount. All blocks in a Page must have the same number of positions (rows) — this enforces the rectangular invariant.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/Page.java:206

        // Avoid creating new objects when region is same as original page
        if (positionOffset == 0 && length == positionCount) {
            return this;
        }

        // Create a new page view with the specified region
        int channelCount = getChannelCount();
        Block[] slicedBlocks = new Block[channelCount];
        for (int i = 0; i < channelCount; i++) {
            slicedBlocks[i] = blocks[i].getRegion(positionOffset, length);
        }
        return wrapBlocksWithoutCopy(length, slicedBlocks);
    }

    public Page appendColumn(Block block)
    {
        requireNonNull(block, "block is null");
        if (positionCount != block.getPositionCount()) {
            throw new IllegalArgumentException("Block does not have same position count");
        }

        Block[] newBlocks = Arrays.copyOf(blocks, blocks.length + 1);
        newBlocks[blocks.length] = block;
        return wrapBlocksWithoutCopy(positionCount, newBlocks);
    }

    public Page compact()
    {
        if (getRetainedSizeInBytes() <= getSizeInBytes()) {
            return this;
        }

        for (int i = 0; i < blocks.length; i++) {
            Block block = blocks[i];
            if (block instanceof DictionaryBlock) {
                continue;
            }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Ensure the appended block is built from the same rows: verify block.getPositionCount() == page.getPositionCount() before appending.
  2. If sizes differ, slice the block with block.getRegion(0, page.getPositionCount()) or rebuild it for the current page batch.
  3. Fix the upstream operator so the mask/hash column is computed per page batch, not reused across batches.
  4. Add an assert or test comparing position counts before appendColumn in custom code.

Example fix

// before
page.appendColumn(hashBlockBuiltForPreviousBatch);
// after
checkState(hashBlock.getPositionCount() == page.getPositionCount(), "position count mismatch");
page.appendColumn(hashBlock);
Defensive patterns

Strategy: validation

Validate before calling

boolean canAppendColumn(Page page, Block block) {
    return page != null && block != null && page.getPositionCount() == block.getPositionCount();
}

Type guard

Page safeAppendColumn(Page page, Block block) {
    if (page == null || block == null || page.getPositionCount() != block.getPositionCount()) {
        return null;
    }
    return page.appendColumn(block);
}

Try / catch

try {
    return page.appendColumn(block);
} catch (IllegalArgumentException e) {
    throw new IllegalStateException(format("Cannot append block of %d rows to page of %d rows", block.getPositionCount(), page.getPositionCount()), e);
}

Prevention

When it happens

Trigger: Calling page.appendColumn(block) where block.getPositionCount() != page.getPositionCount(), e.g. appending a lookup/mask/hash block computed over a different number of rows, or appending a single-row constant block to a 1000-row page.

Common situations: Custom connectors or page processors joining blocks built from mismatched input sizes, hash/mask pages built against one batch then appended to another, or filter operators not accounting for reduced row counts after filtering.

Related errors


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