quickwit-oss/quickwit · error

error parsing routing expression: {e}

Error message

error parsing routing expression: {e}

What it means

The routing expression (partitioning key expression) DSL string is parsed with a nom parser. If the whole string cannot be parsed as a valid routing expression (bad syntax, unbalanced characters, unknown constructs), the parser error is wrapped with this message. It occurs when index partitioning configuration is being interpreted.

Source

Thrown at quickwit/quickwit-doc-mapper/src/routing_expression/mod.rs:388

    use nom::{AsChar, Finish, IResult, Input, Parser};

    // this is a RoutingSubExpr in our DSL.
    #[derive(Debug, PartialEq, Eq, Clone)]
    pub(crate) enum ExpressionAst {
        Field(String),
        Function { name: String, args: Vec<Argument> },
    }

    #[derive(Debug, PartialEq, Eq, Clone)]
    pub(crate) enum Argument {
        Expression(Vec<ExpressionAst>),
        Number(u64),
    }

    pub(crate) fn parse_expression(expr_dsl_str: &str) -> anyhow::Result<Vec<ExpressionAst>> {
        let (i, res) = routing_expr(expr_dsl_str)
            .finish()
            .map_err(|e| anyhow::anyhow!("error parsing routing expression: {e}"))?;
        eof::<_, ()>(i)?;

        Ok(res)
    }

    // tag, but ignore leading and trailing whitespaces
    pub fn wtag<'a, Error: nom::error::ParseError<&'a str>>(
        t: &'a str,
    ) -> impl Parser<&'a str, Output = &'a str, Error = Error> {
        delimited(multispace0, tag(t), multispace0)
    }

    // DSL:
    //
    // RoutingExpr := RoutingSubExpr [ , RoutingExpr ]
    // RougingSubExpr := Identifier [ \( Arguments \) ]
    // Identifier := FieldChar [ Identifier ]
    // FieldChar := { a..z | A..Z | 0..9 | _ | . | \ | / | @ | $ }

View on GitHub (pinned to a39730c5cd)

Solutions

  1. Check the wrapped parser error `{e}` for position/details and correct the DSL string syntax.
  2. Verify parentheses and the `hash_mod(...)` expression shape in `indexing.partitioning`.
  3. Escape special characters in field names per the routing expression DSL rules.
  4. Test the expression against the documented routing expression grammar for your Quickwit version.

Example fix

# before
partitioning:
  hash_mod: tenant_id
# after
partitioning:
  hash_mod: tenant_id
Defensive patterns

Strategy: try-catch

Validate before calling

// Basic syntax sanity check before applying config
if (!/^hash_mod\([a-zA-Z0-9_.\\]+\)$/.test(expr) && expr.trim() !== "") {
    throw new Error("invalid routing expression syntax");
}

Try / catch

match parse_expression(expr) {
    Err(e) if e.to_string().starts_with("error parsing routing expression") => {
        // surface the wrapped nom error position to the user
    }
    r => r?,
}

Prevention

When it happens

Trigger: Calling `parse_expression` on a `routing_expression` / partitioning DSL string from the index config that is syntactically invalid, e.g. `hash_mod(field_name`, stray characters, or missing closing parentheses.

Common situations: Hand-written `indexing.partitioning` config with typos, generated config where a field name contains characters the DSL treats specially, or copy-paste from docs of a different version with changed syntax.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08). Data as JSON: /api/errors/92fa9bc389b56e07. Report an issue: GitHub.