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
- Inspect the wrapped error message for the actual DataFusion evaluation error and the expression/batch dumped in the panic message
- Verify the rewritten expression's input columns all exist in the RecordBatch schema with matching types
- Check the field-name rewrite mapping so the expression is not left referencing the original (unrewritten) column names
- 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
- Always assert expression column refs exist in the batch schema before evaluating
- Keep field-name rewrites consistent between expression and batch schema
- Pin the DataFusion version in CI and run predicate tests on upgrades
- Return typed errors instead of panics in production code paths
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
- Error computing AND
- Expected scalar value
- datafusion error
- error while executing plan
- Expected array value
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)