{"record":{"id":"f114b99436bfbf88","repo":"quickwit-oss/quickwit","slug":"tag-field-tag-field-name-should-not-end-with-a","errorCode":null,"errorMessage":"tag field `{tag_field_name}` should not end with a `.`","messagePattern":"tag field `(.+?)` should not end with a `\\.`","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-doc-mapper/src/doc_mapper/doc_mapper_impl.rs","lineNumber":315,"sourceCode":"            mode: doc_mapping.mode,\n            tokenizer_entries: doc_mapping.tokenizers,\n            tokenizer_manager,\n        })\n    }\n}\n\n/// Checks that a given field name is a valid candidate for a tag.\n///\n/// The conditions are:\n/// - the field must be str, u64, or i64\n/// - if str, the field must use the `raw` tokenizer for indexing.\n/// - the field must be indexed.\nfn validate_tag(tag_field_name: &str, schema: &Schema) -> Result<(), anyhow::Error> {\n    if tag_field_name.starts_with('.') || tag_field_name.starts_with(\"\\\\.\") {\n        bail!(\"tag field `{tag_field_name}` should not start with a `.`\");\n    }\n    if tag_field_name.ends_with('.') {\n        bail!(\"tag field `{tag_field_name}` should not end with a `.`\");\n    }\n    let field = schema\n        .get_field(tag_field_name)\n        .with_context(|| format!(\"unknown tag field: `{tag_field_name}`\"))?;\n    let field_type = schema.get_field_entry(field).field_type();\n    match field_type {\n        FieldType::Str(options) => {\n            let tokenizer_opt = options\n                .get_indexing_options()\n                .map(|text_options: &tantivy::schema::TextFieldIndexing| text_options.tokenizer());\n            if tokenizer_opt != Some(RAW_TOKENIZER_NAME) {\n                bail!(\"tags collection is only allowed on text fields with the `raw` tokenizer\");\n            }\n        }\n        FieldType::U64(_) | FieldType::I64(_) => {\n            // u64 and i64 are accepted as tags.\n        }\n        _ => {","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-doc-mapper/src/doc_mapper/doc_mapper_impl.rs#L297-L333","documentation":"Doc-mapper validation (`validate_tag`, called when building the mapper) found a tag field whose name terminates with a dot. Trailing dots create ambiguity with Quickwit's dotted nested-field path syntax and would produce invalid pruned tags, so the name is rejected.","triggerScenarios":"`QuickwitDocMapper::try_from` validating a `doc_mapping.tag_fields` entry that ends with `.`.","commonSituations":"Trailing punctuation left from copy-paste or from joining a path with dots manually.","solutions":["Strip the trailing `.` from the tag field name in the config."],"exampleFix":"# before\ntag_fields: [service.]\n\n# after\ntag_fields: [service]","handlingStrategy":"validation","validationCode":"fn check_tag_trailing_dot(cfg: &serde_yaml::Value) -> Result<(), String> {\n    if let Some(tags) = cfg[\"doc_mapping\"][\"tag_fields\"].as_sequence() {\n        for t in tags {\n            let name = t.as_str().unwrap_or_default();\n            if name.ends_with('.') {\n                return Err(format!(\"tag field `{name}` ends with a dot\"));\n            }\n        }\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = QuickwitDocMapper::try_from(&index_config) {\n    if e.to_string().contains(\"should not end with\") {\n        eprintln!(\"Strip trailing dot from tag field: {e}\");\n    }\n    return Err(e);\n}","preventionTips":["Trim punctuation from tag field names after copy-paste.","Use the same path constants for field mappings and tag fields.","Add a trailing-dot lint to config CI checks."],"tags":["config","tag-fields","naming"],"backgroundTag":"invalid-identifier-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"}