influxdata/influxdb · error

Unexpected content in ValueExpr

Error message

Unexpected content in ValueExpr

What it means

`ValueExpr::replace_col` panics with unreachable!() when the wrapped expr is not an `Expr::BinaryExpr`. ValueExpr is a typed wrapper guaranteeing the inner expr is a BinaryExpr whose left side is the `_value` column (enforced by TryFrom<Expr>), so this only fires if the invariant was bypassed — e.g. a ValueExpr constructed via unsafe/private means or the struct definition changed.

Solutions

  1. Only create ValueExpr via TryFrom<Expr> / expr.try_into() and handle the Err variant instead of unwrapping into a bad ValueExpr
  2. Confirm the expr passed through try_from was not modified after conversion
  3. If you construct ValueExpr within the crate, reuse TryFrom rather than struct-literal initialization
  4. Replace the panic with an Option/Result return to make the invariant failure recoverable

Example fix

// before
let ve = ValueExpr { expr: some_expr }; // bypasses invariant
let rewritten = ve.replace_col("field");
// after
let ve = ValueExpr::try_from(some_expr)
    .map_err(|_| anyhow::anyhow!("expr is not a _value binary expr"))?;
let rewritten = ve.replace_col("field");
Defensive patterns

Strategy: type-guard

Validate before calling

fn can_replace_col(expr: &Expr, value_col: &str) -> bool {
    matches!(expr, Expr::BinaryExpr(b) if matches!(b.left.as_ref(), Expr::Column(c) if c.name == value_col))
}

Type guard

fn as_value_expr(expr: Expr) -> Option<ValueExpr> {
    ValueExpr::try_from(expr).ok()
}

Try / catch

// Rust: conversion is fallible, handle Err instead of unwrapping
let ve = match ValueExpr::try_from(expr) {
    Ok(ve) => ve,
    Err(orig) => return Err(anyhow!("not a _value binary expr: {orig:?}")),
};

Prevention

When it happens

Trigger: Calling replace_col on a ValueExpr whose internal expr was mutated or constructed outside TryFrom<Expr> (bypassing the `_value`-column BinaryExpr check), e.g. `ValueExpr { expr: col("a") }` via struct literal within the crate.

Common situations: Crate-internal refactors that construct ValueExpr directly instead of via try_from; tests hand-building ValueExpr; version changes altering Expr variants.

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/508080735c9f2bac. Report an issue: GitHub.

Appendix: source

Thrown at core/predicate/src/lib.rs:345

            right: _,
        }) = &expr
            && let Expr::Column(inner) = left.as_ref()
            && inner.name == VALUE_COLUMN_NAME
        {
            return Ok(Self { expr });
        }
        Err(expr)
    }
}

impl ValueExpr {
    /// Returns a new [`Expr`] with the reference to the `_value`
    /// column replaced with the specified column name
    pub fn replace_col(&self, name: &str) -> Expr {
        if let Expr::BinaryExpr(BinaryExpr { left: _, op, right }) = &self.expr {
            binary_expr(name.as_expr(), *op, right.as_ref().clone())
        } else {
            unreachable!("Unexpected content in ValueExpr")
        }
    }
}

impl From<ValueExpr> for Expr {
    fn from(value_expr: ValueExpr) -> Self {
        value_expr.expr
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use data_types::{MAX_NANO_TIME, MIN_NANO_TIME};
    use datafusion::prelude::{col, lit};

    #[test]
    fn test_default_predicate_is_empty() {

View on GitHub (pinned to 06200ef96b)