influxdata/influxdb · error

Unexpected err evaluating

Error message

Unexpected err evaluating {expr:?} against {batch:?}: {e}

What it means

This is a deliberate panic in test helper code: when evaluating a rewritten DataFusion expression against a RecordBatch, evaluating returned Err, or a scalar result could not be converted to an array. The helper treats any evaluation failure as a hard failure because in this test context every expression is expected to evaluate successfully on the batch.

Solutions

  1. Inspect the wrapped error message for the actual DataFusion evaluation error and the expression/batch dumped in the panic message
  2. Verify the rewritten expression's input columns all exist in the RecordBatch schema with matching types
  3. Check the field-name rewrite mapping so the expression is not left referencing the original (unrewritten) column names
  4. Pin or adapt to the DataFusion version being used, since evaluation kernels can change behavior across releases

Example fix

// before
Ok(ColumnarValue::Scalar(s)) => s.to_array_of_size(batch.num_rows()).unwrap_or_else(|e| panic!("Unexpected err ...: {e}")),
// after
Ok(ColumnarValue::Scalar(s)) => s.to_array_of_size(batch.num_rows()).unwrap_or_else(|e| {
    // debug: ensure expr columns exist in batch before evaluating
    assert!(expr_columns_in_schema(&expr, batch.schema()), "expr references missing columns");
    panic!("eval failure: {e}")
}),
Defensive patterns

Strategy: try-catch

Validate before calling

// Rust: verify expr columns exist in batch before evaluating
fn expr_columns_in_schema(expr: &Expr, schema: SchemaRef) -> bool {
    expr.column_refs().iter().all(|c| schema.field_with_name(&c.name).is_ok())
}

Type guard

fn is_ok_result<T>(r: &Result<T, DataFusionError>) -> bool { r.is_ok() }

Try / catch

match evaluate(&expr, &batch) {
    Ok(ColumnarValue::Array(a)) => a,
    Ok(ColumnarValue::Scalar(s)) => s.to_array_of_size(batch.num_rows())? ,
    Err(e) => { log::error!("eval failed for {expr:?}: {e}"); return Err(e); }
}

Prevention

When it happens

Trigger: Calling add_to_predicate (via normalize_predicate or the field_column_rewriter tests) when the rewritten expression's evaluation against the RecordBatch returns Err — e.g. the expression references columns missing from the batch or has a type mismatch after rewriting.

Common situations: Adding a new predicate rewrite rule that produces an expression DataFusion cannot evaluate (wrong input types, unresolvable column); changing the batch schema in tests so the rewritten expression no longer matches; upgrading DataFusion so a kernel now errors on previously-valid input.

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 influxdata/influxdb@06200ef96b (2026-09-19). Data as JSON: /api/errors/58edfef8b47ce3c2. Report an issue: GitHub.

Appendix: source

Thrown at core/predicate/src/rpc_predicate/field_rewrite.rs:173

            // names. For example, if we have two predicates like
            //
            // _field !~= 'f2'
            // _field != 'f3'
            //
            // We will produce two output arrays:
            // ┌─────────┐  ┌─────────┐
            // │  true   │  │  true   │
            // │  false  │  │  true   │
            // │  true   │  │  false  │
            // └─────────┘  └─────────┘
            .map(|expr| match expr.evaluate(&batch) {
                Ok(ColumnarValue::Array(arr)) => arr,
                Ok(ColumnarValue::Scalar(s)) => {
                    s.to_array_of_size(batch.num_rows()).unwrap_or_else(|e| {
                        panic!("Unexpected err converting scalar result from evaluating {expr:?} against {batch:?}: {e}")
                    })
                }
                Err(e) => panic!("Unexpected err evaluating {expr:?} against {batch:?}: {e}"),
            })
            // Now combine the arrays using AND to get a single output
            // boolean array. For the example above, we would get
            // ┌─────────┐
            // │  true   │
            // │  false  │
            // │  false  │
            // └─────────┘
            .reduce(|acc, arr| {
                // apply boolean AND
                let bool_array =
                    kernels::boolean::and(as_boolean_array(&acc), as_boolean_array(&arr))
                        .expect("Error computing AND");
                Arc::new(bool_array) as ArrayRef
            })
            .unwrap();

        assert_eq!(matching.len(), field_names.len());

View on GitHub (pinned to 06200ef96b)