prestodb/presto · error · java.lang.IllegalArgumentException

blocks is empty

Error message

blocks is empty

What it means

Page's constructor requires at least one Block because positionCount is derived from the first block (determinePositionCount). Constructing a Page with zero blocks is meaningless (no channel to determine row count from), so the library throws IllegalArgumentException.

Source

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

        return wrapBlocksWithoutCopy(positionCount, blocks);
    }

    @Override
    public String toString()
    {
        StringBuilder builder = new StringBuilder("Page{");
        builder.append("positions=").append(positionCount);
        builder.append(", channels=").append(getChannelCount());
        builder.append('}');
        builder.append("@").append(Integer.toHexString(System.identityHashCode(this)));
        return builder.toString();
    }

    private static int determinePositionCount(Block... blocks)
    {
        requireNonNull(blocks, "blocks is null");
        if (blocks.length == 0) {
            throw new IllegalArgumentException("blocks is empty");
        }

        return blocks[0].getPositionCount();
    }

    public Page getPositions(int[] retainedPositions, int offset, int length)
    {
        requireNonNull(retainedPositions, "retainedPositions is null");

        Block[] blocks = new Block[this.blocks.length];
        for (int i = 0; i < blocks.length; i++) {
            blocks[i] = this.blocks[i].getPositions(retainedPositions, offset, length);
        }
        return wrapBlocksWithoutCopy(length, blocks);
    }

    public Page copyPositions(int[] retainedPositions, int offset, int length)
    {

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Ensure at least one block (e.g. a constant or row-number block) is always included in the page
  2. If a zero-column result is legitimate, use a different representation (e.g. a page with a constant 'true' marker block)
  3. Fix the projection logic so it never passes an empty blocks array to the Page constructor

Example fix

// before
Page page = new Page(); // throws
// after
if (blocks.length == 0) {
    blocks = new Block[]{new RunLengthEncodedBlock(TRUE_CONSTANT, 0)};
}
Page page = new Page(blocks);
Defensive patterns

Strategy: validation

Validate before calling

if (blocks == null || blocks.length == 0) {
    throw new IllegalArgumentException("cannot construct Page with zero blocks");
}
Page page = new Page(blocks);

Type guard

boolean canBuildPage(Block[] blocks) {
    return blocks != null && blocks.length > 0;
}

Try / catch

try {
    page = new Page(blocks);
} catch (IllegalArgumentException e) {
    if (!e.getMessage().contains("blocks is empty")) throw e;
    page = new Page(RunLengthEncodedBlock.TRUE_CONSTANT_BLOCK, 0); // or skip operator
}

Prevention

When it happens

Trigger: new Page() with an empty Block[] or no arguments — e.g. building a page from an empty list of columns, or a connector that returns zero output channels.

Common situations: Dynamic column projection that can produce zero columns; aggregation code that builds a page only from optional columns; bugs where a single-column page's only block was removed.

Related errors


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