prestodb/presto · error · IllegalArgumentException

slice is null

Error message

slice is null

What it means

VariableWidthBlock stores variable-length values in a Slice plus an offsets array; a null backing slice cannot hold any data, so the constructor throws IllegalArgumentException. The slice is required even for zero-position blocks.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/block/VariableWidthBlock.java:80

    public VariableWidthBlock(int positionCount, Slice slice, int[] offsets, Optional<boolean[]> valueIsNull)
    {
        this(0, positionCount, slice, offsets, valueIsNull.orElse(null));
    }

    VariableWidthBlock(int arrayOffset, int positionCount, Slice slice, int[] offsets, boolean[] valueIsNull)
    {
        if (arrayOffset < 0) {
            throw new IllegalArgumentException("arrayOffset is negative");
        }
        this.arrayOffset = arrayOffset;
        if (positionCount < 0) {
            throw new IllegalArgumentException("positionCount is negative");
        }
        this.positionCount = positionCount;

        if (slice == null) {
            throw new IllegalArgumentException("slice is null");
        }
        this.slice = slice;

        if (offsets.length - arrayOffset < (positionCount + 1)) {
            throw new IllegalArgumentException("offsets length is less than positionCount");
        }
        this.offsets = offsets;

        if (valueIsNull != null && valueIsNull.length - arrayOffset < positionCount) {
            throw new IllegalArgumentException("valueIsNull length is less than positionCount");
        }
        this.valueIsNull = valueIsNull;

        sizeInBytes = offsets[arrayOffset + positionCount] - offsets[arrayOffset] + ((Integer.BYTES + Byte.BYTES) * (long) positionCount);
        retainedSizeInBytes = INSTANCE_SIZE + slice.getRetainedSize() + sizeOf(valueIsNull) + sizeOf(offsets);
    }

    @Override

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Pass Slices.EMPTY_SLICE (or an empty wrapped buffer) instead of null.
  2. Fix upstream deserialization to never emit null slices for empty pages.
  3. In test code, build blocks via the VariableWidthBlockBuilder rather than raw constructors.

Example fix

// before
new VariableWidthBlock(0, 0, null, offsets, null); // throws
// after
new VariableWidthBlock(0, 0, Slices.EMPTY_SLICE, offsets, null);
Defensive patterns

Strategy: validation

Validate before calling

Slice data = (rawSlice != null) ? rawSlice : Slices.EMPTY_SLICE;

Try / catch

try {
    new VariableWidthBlock(0, positionCount, slice, offsets, valueIsNull);
} catch (IllegalArgumentException e) {
    // null slice: rebuild with empty slice
}

Prevention

When it happens

Trigger: Passing a null Slice to a VariableWidthBlock constructor, e.g. when a deserializer gets an empty/uninitialized buffer and forwards null instead of Slices.EMPTY_SLICE.

Common situations: Deserialization paths where a missing column page yields null instead of an empty slice; tests constructing blocks by hand with null data.

Related errors


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