{"record":{"id":"bfb5ba865fb5f72e","repo":"quickwit-oss/quickwit","slug":"retention-policy-requires-a-timestamp-field-but-d","errorCode":null,"errorMessage":"retention policy requires a timestamp field, but doc mapping does not declare one","messagePattern":"retention policy requires a timestamp field, but doc mapping does not declare one","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-config/src/index_config/mod.rs","lineNumber":692,"sourceCode":"/// to a method on `IndexConfig` so we can reuse it for validating index templates.\npub(super) fn validate_index_config(\n    doc_mapping: &DocMapping,\n    indexing_settings: &IndexingSettings,\n    search_settings: &SearchSettings,\n    retention_policy_opt: &Option<RetentionPolicy>,\n) -> anyhow::Result<()> {\n    // Note: this needs a deep refactoring to separate the doc mapping configuration,\n    // and doc mapper implementations.\n    // TODO see if we should store the byproducton the IndexConfig.\n    build_doc_mapper(doc_mapping, search_settings)?;\n\n    indexing_settings.merge_policy.validate()?;\n    indexing_settings.resources.validate()?;\n\n    if let Some(retention_policy) = retention_policy_opt {\n        retention_policy.validate()?;\n\n        ensure!(\n            doc_mapping.timestamp_field.is_some(),\n            \"retention policy requires a timestamp field, but doc mapping does not declare one\"\n        );\n    }\n    Ok(())\n}\n\n/// Returns the updated doc mapping and a boolean indicating whether a mutation occurred.\n///\n/// The logic goes as follows:\n/// 1. If the new doc mapping is the same as the current doc mapping, ignoring their UIDs, returns\n///    the current doc mapping and `false`, indicating that no mutation occurred.\n/// 2. If the new doc mapping is different from the current doc mapping, verifies the following\n///    constraints before returning the new doc mapping and `true`, indicating that a mutation\n///    occurred:\n///    - The doc mapping UID should differ from the current one\n///    - The timestamp field should remain the same\n///    - The tokenizers should be a superset of the current tokenizers","sourceCodeStart":674,"sourceCodeEnd":710,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-config/src/index_config/mod.rs#L674-L710","documentation":"A retention policy deletes documents based on their timestamp field. validate_index_config therefore requires that, whenever a retention policy is present, the doc mapping declares a timestamp_field; otherwise there is no column to evaluate retention against, and config build fails.","triggerScenarios":"Submitting an index config (via CreateIndex, IndexConfig::load, or config update validation) that sets a `retention` policy while `doc_mapping.timestamp_field` is absent.","commonSituations":"Adding a retention policy to an existing index that never had a timestamp field; copying a retention snippet into a logs config without declaring timestamp_field; schema generated from data that omitted the timestamp field.","solutions":["Declare `timestamp_field` in doc_mapping pointing at a valid datetime field","Or remove the retention policy if time-based deletion is not needed","Ensure the referenced field has a datetime fast/typed mapping so retention can evaluate it"],"exampleFix":"# before\ndoc_mapping:\n  field_mappings:\n    - name: ts\n      type: datetime\nretention:\n  period: 30 days\n# after\ndoc_mapping:\n  timestamp_field: ts\n  field_mappings:\n    - name: ts\n      type: datetime\nretention:\n  period: 30 days","handlingStrategy":"validation","validationCode":"# Python precheck\nif cfg.get(\"retention\") and not cfg.get(\"doc_mapping\", {}).get(\"timestamp_field\"):\n    raise ValueError(\"retention requires doc_mapping.timestamp_field\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Declare timestamp_field whenever you use retention, partitioning or pruning features","Validate index configs with quickwit's config validation before submitting","Template retention+timestamp together in index config generators"],"tags":["config","retention","validation","schema"],"backgroundTag":"missing-required-config-field","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"}