risingwavelabs/risingwave · error · ArrayError

Must have no buffer in a list array

Error message

Must have no buffer in a list array

What it means

`ListArray::from_protobuf` expects the list array's own protobuf representation to contain no direct value buffers, because list elements are stored nested in `array_data.value`, not in `values`. If `array.values` is non-empty, the payload does not follow the list-array encoding and decoding fails.

Source

Thrown at src/common/src/array/list_array.rs:250

    ///
    /// ```text
    /// [[1,2,3],NULL,[4,5]] => [1,2,3,4,5]
    /// [[[1],[2]],[[3],[4]]] => [1,2,3,4]
    /// ```
    pub fn flatten(&self) -> ArrayImpl {
        match &*self.value {
            ArrayImpl::List(inner) => inner.flatten(),
            a => a.clone(),
        }
    }

    /// Return the inner array of the list array.
    pub fn values(&self) -> &ArrayImpl {
        &self.value
    }

    pub fn from_protobuf(array: &PbArray) -> ArrayResult<ArrayImpl> {
        ensure!(
            array.values.is_empty(),
            "Must have no buffer in a list array"
        );
        debug_assert!(
            (array.array_type == PbArrayType::List as i32)
                || (array.array_type == PbArrayType::Map as i32),
            "invalid array type for list: {}",
            array.array_type
        );
        let bitmap: Bitmap = array.get_null_bitmap()?.into();
        let array_data = array.get_list_array_data()?.to_owned();
        let flatten_len = match array_data.offsets.last() {
            Some(&n) => n as usize,
            None => bail!("Must have at least one element in offsets"),
        };
        let value = ArrayImpl::from_protobuf(array_data.value.as_ref().unwrap(), flatten_len)?;
        let arr = ListArray {
            bitmap,

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Confirm the PbArray was produced by `ListArray::to_protobuf`, which leaves `values` empty and fills `array_data` instead.
  2. Verify `array_type` is List or Map before decoding.
  3. Check for version skew where the serialization format of list arrays changed.
  4. Fix test/tooling code that builds PbArray manually to not set `values` for lists.

Example fix

// before (mis-encoded flat array decoded as list)
let arr = ListArray::from_protobuf(&pb_array)?;
// after: route by array type
match pb_array.array_type() {
    PbArrayType::List | PbArrayType::Map => ListArray::from_protobuf(&pb_array),
    _ => ArrayImpl::from_protobuf(&pb_array, cardinality),
}
Defensive patterns

Strategy: validation

Validate before calling

if !pb_array.values.is_empty() { return Err("list array must have no direct buffers".into()); }

Type guard

fn is_list_encoded(a: &PbArray) -> bool {
    (a.array_type == PbArrayType::List as i32 || a.array_type == PbArrayType::Map as i32) && a.values.is_empty()
}

Prevention

When it happens

Trigger: Calling `ListArray::from_protobuf(&pb_array)` when `pb_array.values` contains buffers — typically because the payload was produced for a flat array type (e.g. Int32Array) or hand-assembled incorrectly.

Common situations: Mislabeling `array_type` so a flat array is decoded as a list; corrupted stream chunks after schema changes; manually constructing PbArray in tests or tools.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/69ffa4844bf2356a. Report an issue: GitHub.