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_serdeView on GitHub (pinned to 6469eb736d)
Solutions
- Ensure the clean watermark column is part of the table's value columns, not only the primary key
- Recreate the table/mv so value_indices includes the watermark column index
- Check the table catalog and column index computation for off-by-one or stale indices after schema change
- 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
- Keep the clean watermark column in the table's value columns
- Recompute value_indices whenever the table schema changes
- Add an init-time assertion that all key columns appear in the layout
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
- Storage error: {0}
- Serialize/deserialize error: {0}
- next offset {:?} should be later than current offset {:?}
- new item epoch {} does not match current chunk offset epoch
- new item epoch {} does not exceed barrier offset epoch {}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/0f091ff39f9862f9.
Report an issue: GitHub.