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
- Check the wrapped parser error `{e}` for position/details and correct the DSL string syntax.
- Verify parentheses and the `hash_mod(...)` expression shape in `indexing.partitioning`.
- Escape special characters in field names per the routing expression DSL rules.
- 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
- Copy routing expressions verbatim from docs and adjust only field names.
- Escape special characters in field names in the DSL.
- Test partitioning config on a dev index before production.
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
- invalid arguments for `hash_mod`: expected 2 arguments, foun
- invalid 1st argument for `hash_mod`: expected expression
- invalid 2nd argument for `hash_mod`: expected number
- unknown function `{}`
- error parsing key expression: {e}
AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08).
Data as JSON: /api/errors/92fa9bc389b56e07.
Report an issue: GitHub.