risingwavelabs/risingwave · error · StreamExecutorError

clean watermark column index

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.

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.

Appendix: 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)