{"record":{"id":"f8832a641aef4ebc","repo":"quickwit-oss/quickwit","slug":"error-parsing-key-expression-e","errorCode":null,"errorMessage":"error parsing key expression: {e}","messagePattern":"error parsing key expression: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-doc-mapper/src/routing_expression/mod.rs","lineNumber":491,"sourceCode":"\n    /// Parse a single path component, separated by dots. De-escape any escaped dot it may contain.\n    fn escaped_key(input: &str) -> IResult<&str, Cow<'_, str>> {\n        map(escaped(key_identifier, '\\\\', tag(\".\")), |s: &str| {\n            if s.contains(\"\\\\.\") {\n                Cow::Owned(s.replace(\"\\\\.\", \".\"))\n            } else {\n                Cow::Borrowed(s)\n            }\n        })\n        .parse(input)\n    }\n\n    /// Parse a field name into a path, de-escaping where appropriate.\n    pub(crate) fn parse_field_name(input: &str) -> anyhow::Result<Vec<Cow<'_, str>>> {\n        let (i, res) = separated_list0(tag(\".\"), escaped_key)\n            .parse(input)\n            .finish()\n            .map_err(|e| anyhow::anyhow!(\"error parsing key expression: {e}\"))?;\n        eof::<_, ()>(i)?;\n        Ok(res)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use std::collections::HashSet;\n\n    use super::*;\n\n    #[track_caller]\n    fn test_ser_deser(expr: &InnerRoutingExpr) {\n        let ser = expr.to_string();\n        assert_eq!(&InnerRoutingExpr::from_str(&ser).unwrap(), expr);\n    }\n\n    #[track_caller]","sourceCodeStart":473,"sourceCodeEnd":509,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-doc-mapper/src/routing_expression/mod.rs#L473-L509","documentation":"Field names inside routing expressions are parsed as a dot-separated list of escaped keys. If a key segment is malformed (illegal characters, trailing dot, bad escape), the nom parser fails and the error is wrapped with this message. It is a sub-step of parsing routing/partitioning expressions.","triggerScenarios":"`parse_field_name` receives a key string from a routing expression containing an invalid key: an unescaped special character, an empty segment (e.g. `a..b` or trailing `.`), or a malformed escape sequence.","commonSituations":"Field names containing dots not escaped with backslash, accidental whitespace or punctuation in the partitioning key path, or auto-generated expressions from field names with unusual characters.","solutions":["Fix the key per the wrapped error: escape special characters (e.g. literal dots) with backslashes.","Remove empty segments such as double dots or a trailing dot.","Use the exact field name as defined in the index mapping, with proper escaping.","If the field name is unmanageable, rename the field in the mapping to an identifier-safe name."],"exampleFix":"// before\n\"tenant.id\"\n// after\n\"tenant\\\\.id\"","handlingStrategy":"validation","validationCode":"fn valid_key(k: &str) -> bool {\n    !k.is_empty() && !k.starts_with('.') && !k.ends_with('.') && !k.contains(\"..\")\n}\n// ensure every dot-separated segment passes valid_key","typeGuard":null,"tryCatchPattern":"match parse_field_name(input) {\n    Err(e) if e.to_string().contains(\"error parsing key expression\") => {\n        // escape or correct the field-name key\n    }\n    r => r?,\n}","preventionTips":["Escape literal dots in field names with backslashes in routing expressions.","Avoid empty key segments (double dots, leading/trailing dots).","Prefer identifier-safe field names in mapped schemas."],"tags":["parser","routing","field-name","escaping"],"backgroundTag":"invalid-argument-format","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"}