{"record":{"id":"6f4b2a5a14a5df23","repo":"quickwit-oss/quickwit","slug":"invalid-arguments-for-hash-mod-expected-2-argum","errorCode":null,"errorMessage":"invalid arguments for `hash_mod`: expected 2 arguments, found {}","messagePattern":"invalid arguments for `hash_mod`: expected 2 arguments, found (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-doc-mapper/src/routing_expression/mod.rs","lineNumber":292,"sourceCode":"}\n\nfn convert_ast(ast: Vec<expression_dsl::ExpressionAst>) -> anyhow::Result<InnerRoutingExpr> {\n    use expression_dsl::{Argument, ExpressionAst};\n\n    let mut result = ast\n        .into_iter()\n        .map(|ast_elem| match ast_elem {\n            ExpressionAst::Field(field_name) => {\n                let field_path = expression_dsl::parse_field_name(&field_name)?\n                    .into_iter()\n                    .map(Cow::into_owned)\n                    .collect();\n                Ok(InnerRoutingExpr::Field(field_path))\n            }\n            ExpressionAst::Function { name, mut args } => match &*name {\n                \"hash_mod\" => {\n                    if args.len() != 2 {\n                        anyhow::bail!(\n                            \"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                }","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-doc-mapper/src/routing_expression/mod.rs#L274-L310","documentation":"The routing expression parser requires the `hash_mod` function to receive exactly two arguments: an expression (the field path to hash) and a number (the modulo). `convert_ast` bails with this message when the argument count differs, interpolating the actual count found.","triggerScenarios":"Calling `RoutingExpr::from_str` (or the AST converter directly) with a routing expression like `hash_mod(field)` or `hash_mod(a, b, 10)` — i.e. any `hash_mod(...)` with an argument count other than 2.","commonSituations":"Typo or misunderstanding of `hash_mod` syntax in index config `routing_expression`; forgetting the modulo argument (e.g. `hash_mod(tenant_id)`); programmatic generation of routing expressions with wrong arity.","solutions":["Provide exactly two arguments: an expression and a number, e.g. `hash_mod(tenant_id, 10)`.","If you only want one field with no modulo, use the plain field form `tenant_id` instead of `hash_mod`.","Check the index config's routing_expression string for missing/extra commas or arguments and reload the index config."],"exampleFix":"// before (index config)\nrouting_expression: hash_mod(tenant_id)\n// after\nrouting_expression: hash_mod(tenant_id, 4)","handlingStrategy":"validation","validationCode":"let expr = \"hash_mod(tenant_id, 4)\";\n// count top-level args by rough parse or validate before handing to RoutingExpr::from_str\nif !expr.starts_with(\"hash_mod(\") || expr.matches(',').count() != 1 {\n    return Err(\"hash_mod requires exactly 2 arguments: expression, number\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write hash_mod with exactly two arguments: field expression and integer modulo.","Validate routing expressions in CI by calling RoutingExpr::from_str on config fixtures.","Keep routing expressions simple; prefer plain field form when no modulo is needed."],"tags":["routing","config","argument-count"],"backgroundTag":"missing-required-argument","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"}