risingwavelabs/risingwave · error

below watermark check condition eval must return bool array

Error message

below watermark check condition eval must return bool array

What it means

Companion panic to the dynamic-filter one: the optional `below_watermark_condition` expression (used for state cleaning) is expected to evaluate to a Bool array over the chunk. If eval_infallible returns any non-boolean array, the executor cannot decide which rows are below the cleaning watermark and panics. This is an internal contract between the frontend planner (which builds the below-watermark expression) and this executor.

Source

Thrown at src/stream/src/executor/dynamic_filter.rs:128

        for (idx, (op, row)) in chunk.rows().enumerate() {
            let left_val = row.datum_at(self.key_l).to_owned_datum();

            let satisfied_dyn_filter_cond = if let Some(array) = &filter_results {
                if let ArrayImpl::Bool(results) = &**array {
                    results.value_at(idx).unwrap_or(false)
                } else {
                    panic!("dynamic filter condition eval must return bool array")
                }
            } else {
                // A NULL right value implies a false evaluation for all rows
                false
            };
            let below_watermark = if let Some(array) = &below_watermark {
                if let ArrayImpl::Bool(results) = &**array {
                    results.value_at(idx).unwrap_or(false)
                } else {
                    panic!("below watermark check condition eval must return bool array")
                }
            } else {
                // there was no state cleaning watermark before
                false
            };

            match op {
                Op::Insert | Op::Delete => {
                    new_ops.push(op);
                    if satisfied_dyn_filter_cond {
                        new_visibility.append(true);
                    } else {
                        new_visibility.append(false);
                    }
                }
                Op::UpdateDelete => {
                    last_res = satisfied_dyn_filter_cond;
                }

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Verify the below-watermark condition is planned as a Boolean expression (check return_type inference in the frontend for dynamic filter state cleaning).
  2. Diff recent planner changes affecting watermark condition generation; revert or fix the non-boolean expression construction.
  3. Replace the panic with a StreamExecutorError::internal carrying the actual array type to aid debugging, then re-run the madsim/e2e tests for dynamic filter.

Example fix

// before
} else { panic!("below watermark check condition eval must return bool array") }
// after
} else {
    return Err(StreamExecutorError::internal(anyhow::anyhow!(
        "below watermark condition eval must return Bool array, got {}",
        array.data_type()
    )));
}
Defensive patterns

Strategy: type-guard

Validate before calling

if let Some(array) = &below_watermark {
    assert!(matches!(&**array, ArrayImpl::Bool(_)), "below-watermark cond must eval to Bool array");
}

Type guard

fn is_bool_array(a: &ArrayImpl) -> bool { matches!(a, ArrayImpl::Bool(_)) }

Try / catch

match &**array {
    ArrayImpl::Bool(b) => b.value_at(idx).unwrap_or(false),
    other => return Err(StreamExecutorError::internal(anyhow::anyhow!("below-watermark cond returned {:?}", other.data_type()))),
}

Prevention

When it happens

Trigger: apply_batch is called with Some(below_watermark_condition) and the expression's eval_infallible result is an ArrayImpl other than Bool for the chunk at index idx.

Common situations: Seen only when developing or modifying RisingWave's watermark/state-cleaning planning path, e.g. after changing how the below-watermark predicate is inferred or adding a new key/comparator type that breaks boolean type inference.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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