risingwavelabs/risingwave · error · StreamExecutorError

clean watermark column index {} is not included in table val

Error message

clean watermark column index {} is not included in table value indices {:?}

What it means

When looking up where the clean watermark column lives inside the state table's value_indices mapping, the index was not found among the value column indices. The state table maintains a remapping of logical column indexes to stored value positions; a clean watermark column absent from that mapping means the table layout and the watermark column configuration are inconsistent.

Source

Thrown at src/stream/src/common/table/state_table.rs:2225

                "Watermark serde should have at least one order type"
            ))
        })?;

        let direction = if order_type.is_ascending() {
            WatermarkDirection::Ascending
        } else {
            WatermarkDirection::Descending
        };
        let clean_watermark_index_in_pk = self
            .pk_indices
            .iter()
            .position(|&i| i == clean_watermark_index);
        let clean_watermark_index_in_value = match &self.value_indices {
            Some(value_indices) => value_indices
                .iter()
                .position(|idx| *idx == clean_watermark_index)
                .ok_or_else(|| {
                    StreamExecutorError::from(anyhow!(
                        "clean watermark column index {} is not included in table value indices {:?}",
                        clean_watermark_index,
                        value_indices
                    ))
                })?,
            None => clean_watermark_index,
        };

        let stream = self
            .iter_with_prefix_inner::</* REVERSE */ false, Bytes>(pk_prefix, sub_range, prefetch_options)
            .await?
            .try_filter_map(move |(pk, row)| {
                let should_filter =  match watermark_type {
                    WatermarkSerdeType::PkPrefix => unreachable!(),
                    WatermarkSerdeType::NonPkPrefix => {
                        let table_key = TableKey(pk);
                        let (vnode, key) = table_key.split_vnode();
                        let pk_cols = self.pk_serde

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Ensure the clean watermark column is part of the table's value columns, not only the primary key
  2. Recreate the table/mv so value_indices includes the watermark column index
  3. Check the table catalog and column index computation for off-by-one or stale indices after schema change
  4. Rebuild the state table from the current schema instead of a cached layout

Example fix

// before: value_indices omits the watermark column
value_indices: Some(vec![0, 1]),
// after: include the clean watermark index (2)
value_indices: Some(vec![0, 1, 2]),
Defensive patterns

Strategy: validation

Validate before calling

fn watermark_in_value_indices(idx: usize, value_indices: &Option<Vec<usize>>) -> bool {
    match value_indices {
        Some(v) => v.contains(&idx),
        None => true,
    }
}

Prevention

When it happens

Trigger: Calling the watermark update path with `Some(value_indices)` set where none of the entries equals `clean_watermark_index` — i.e. the clean watermark column is a key column or was dropped from the value layout.

Common situations: Table schema changed (column added/removed) without rebuilding the state table; watermark column configured as part of the primary key while the code expects it in the value columns; stale state table after a materialized view definition change.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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