{"record":{"id":"d1b1e57d6f773436","repo":"quickwit-oss/quickwit","slug":"unknown-function","errorCode":null,"errorMessage":"unknown function `{}`","messagePattern":"unknown function `(.+?)`","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-doc-mapper/src/routing_expression/mod.rs","lineNumber":311,"sourceCode":"                            \"invalid arguments for `hash_mod`: expected 2 arguments, found {}\",\n                            args.len()\n                        );\n                    }\n\n                    let Argument::Expression(fields) = args.remove(0) else {\n                        anyhow::bail!(\"invalid 1st argument for `hash_mod`: expected expression\");\n                    };\n\n                    let Argument::Number(modulo) = args.remove(0) else {\n                        anyhow::bail!(\"invalid 2nd argument for `hash_mod`: expected number\");\n                    };\n\n                    Ok(InnerRoutingExpr::Modulo(\n                        Box::new(convert_ast(fields)?),\n                        modulo,\n                    ))\n                }\n                _ => anyhow::bail!(\"unknown function `{}`\", name),\n            },\n        })\n        .collect::<Result<Vec<_>, _>>()?;\n    if result.is_empty() {\n        Ok(InnerRoutingExpr::default())\n    } else if result.len() == 1 {\n        Ok(result.remove(0))\n    } else {\n        Ok(InnerRoutingExpr::Composite(result))\n    }\n}\n\n// The display implementation should be consistent with `FromString`.\nimpl Display for InnerRoutingExpr {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        match &self {\n            InnerRoutingExpr::Field(field) => {\n                for (index, part) in field.iter().enumerate() {","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-doc-mapper/src/routing_expression/mod.rs#L293-L329","documentation":"The routing expression grammar only recognizes the `hash_mod` function; any other function name in the AST falls through to this catch-all bail in `convert_ast`. It interpolates the unrecognized function name.","triggerScenarios":"Calling `RoutingExpr::from_str` with a function-style expression whose name is not `hash_mod`, e.g. `mod(tenant_id, 4)` or `hash(tenant_id)`.","commonSituations":"Assuming other hash/partition functions exist (e.g. mimicking Elasticsearch `mod`); typos like `hashmode` or `hash_md`; copying routing expressions from other systems.","solutions":["Use the supported function name `hash_mod`: `hash_mod(field, modulo)`.","Correct typos in the function name in the routing_expression config value.","If you need a different partitioning scheme, implement it as an expression without functions or extend the parser upstream."],"exampleFix":"// before\nrouting_expression: mod(tenant_id, 4)\n// after\nrouting_expression: hash_mod(tenant_id, 4)","handlingStrategy":"validation","validationCode":"const ALLOWED_ROUTING_FUNCS: &[&str] = &[\"hash_mod\"];\nfn validate_routing_fn(name: &str) -> Result<(), String> {\n    if ALLOWED_ROUTING_FUNCS.contains(&name) { Ok(()) }\n    else { Err(format!(\"unknown routing function: {}\", name)) }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only use hash_mod in routing expressions; it is the sole supported function.","Keep a reference list of supported routing functions near your config templates.","Catch typos by validating configs at load time, not at indexing time."],"tags":["routing","config","unknown-function"],"backgroundTag":"invalid-argument-value","analyzedSha":"a39730c5cdcd1a4fe798403737ae293999ea21f8","analyzedAt":"2026-09-08T13:19:37.784Z","contentChangedAt":"2026-09-08T13:19:37.784Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}