risingwavelabs/risingwave · error · ArrayError

Must have exactly 1 buffer in a jsonb array

Error message

Must have exactly 1 buffer in a jsonb array

What it means

`JsonbArray::from_protobuf` requires that the protobuf array carries exactly one values buffer whose `body` holds the serialized jsonbb bytes. If `array.values.len() != 1`, the jsonb payload is malformed for this array type and decoding is aborted with this message.

Source

Thrown at src/common/src/array/jsonb_array.rs:110

        Self::ArrayType {
            bitmap: self.bitmap.finish(),
            data: self.builder.finish(),
        }
    }
}

impl JsonbArrayBuilder {
    pub fn writer(&mut self) -> JsonbWriter<'_> {
        JsonbWriter::new(self)
    }
}

impl JsonbArray {
    /// Loads a `JsonbArray` from a protobuf array.
    ///
    /// See also `JsonbArray::to_protobuf`.
    pub fn from_protobuf(array: &PbArray) -> ArrayResult<ArrayImpl> {
        ensure!(
            array.values.len() == 1,
            "Must have exactly 1 buffer in a jsonb array"
        );
        let arr = JsonbArray {
            bitmap: array.get_null_bitmap()?.into(),
            data: jsonbb::Value::from_bytes(&array.values[0].body),
        };
        Ok(arr.into())
    }
}

impl Array for JsonbArray {
    type Builder = JsonbArrayBuilder;
    type OwnedItem = JsonbVal;
    type RefItem<'a> = JsonbRef<'a>;

    unsafe fn raw_value_at_unchecked(&self, idx: usize) -> Self::RefItem<'_> {
        JsonbRef(self.data.as_array().unwrap().get(idx).unwrap())

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Ensure the jsonb array is serialized via `JsonbArray::to_protobuf`, which always emits exactly one values buffer.
  2. Check that the column type in the stream plan matches the actual data type (Jsonb) before deserialization.
  3. If data came from an older version, re-ingest or migrate rather than decoding directly.
  4. Validate `array.values.len() == 1` upstream and return a clearer error.

Example fix

// before
let arr = JsonbArray::from_protobuf(&pb_array)?;
// after
ensure!(pb_array.values.len() == 1, "jsonb array requires exactly 1 buffer, got {}", pb_array.values.len());
let arr = JsonbArray::from_protobuf(&pb_array)?;
Defensive patterns

Strategy: validation

Validate before calling

if pb_array.values.len() != 1 { return Err("jsonb array requires exactly 1 buffer".into()); }

Type guard

fn is_single_buffer_jsonb(a: &PbArray) -> bool {
    a.array_type == PbArrayType::Jsonb as i32 && a.values.len() == 1
}

Prevention

When it happens

Trigger: Calling `JsonbArray::from_protobuf(&pb_array)` when `pb_array.values` is empty or contains more than one buffer (e.g. a buffer produced by a non-jsonb array type was mislabeled as Jsonb).

Common situations: Schema/type mismatches where a column's array type changed but old data remains; corrupted or hand-built protobuf arrays; writing a jsonb array with `to_protobuf` from a mismatched struct.

Related errors


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