{"record":{"id":"72de50ec15718a17","repo":"quickwit-oss/tantivy","slug":"dictionary-missing-for-str-accessor","errorCode":null,"errorMessage":"dictionary missing for str accessor","messagePattern":"dictionary missing for str accessor","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/aggregation/bucket/composite/accessors.rs","lineNumber":455,"sourceCode":"            .downcast_arc::<CompactSpaceU64Accessor>()\n            .map_err(|_| {\n                TantivyError::AggregationError(crate::aggregation::AggregationError::InternalError(\n                    \"type mismatch: could not downcast to CompactSpaceU64Accessor\".to_string(),\n                ))\n            })?;\n        let ip_u128 = key.to_bits();\n        let ip_next_compact = compact_space_accessor.u128_to_next_compact(ip_u128);\n        Ok(ip_next_compact.into())\n    }\n\n    fn precompute_term_ord(\n        str_dict_column: &Option<StrColumn>,\n        key: &str,\n        field: &str,\n    ) -> crate::Result<Self> {\n        let dict = str_dict_column\n            .as_ref()\n            .expect(\"dictionary missing for str accessor\")\n            .dictionary();\n        let next_ord = dict.term_ord_or_next(key).map_err(|_| {\n            TantivyError::InvalidArgument(format!(\n                \"failed to lookup after_key '{}' for field '{}'\",\n                key, field\n            ))\n        })?;\n        Ok(next_ord.into())\n    }\n\n    /// Projects the after key into the column space of the given accessor.\n    ///\n    /// The computed after key will not take care of skipping entire columns\n    /// when the after key type is ordered after the accessor's type, that\n    /// should be performed earlier.\n    pub fn precompute(\n        composite_accessor: &CompositeAccessor,\n        source_after_key: &CompositeIntermediateKey,","sourceCodeStart":437,"sourceCodeEnd":473,"githubUrl":"https://github.com/quickwit-oss/tantivy/blob/b5d8deb80c26924e6b007a5b1a7630f35ca64de4/src/aggregation/bucket/composite/accessors.rs#L437-L473","documentation":"precompute_term_ord needs the term dictionary of a str column to compute term ordinals for composite aggregation buckets, and it .expect()s that the optional StrColumn is present. When str_dict_column is None, the process panics with \"dictionary missing for str accessor\". This means the accessor was built for a field that turned out to have no string dictionary column, violating the assumption made when constructing it.","triggerScenarios":"Running the composite aggregation precompute on a field whose dictionary column is absent: field missing from the segment, field is not a str/keyword column (numeric or text-only), or the segment was built without dictionary for that field.","commonSituations":"Aggregating on a field not indexed as keyword/str; querying segments written before the field existed; typo in field name leading to fallback columns without dictionaries; mixed-type field across segments.","solutions":["Verify the field exists in the schema as a str/keyword column with a dictionary and correct any field-name typos.","Guard the code: return a TantivyError (e.g. InvalidArgument \"field has no dictionary\") instead of expect when str_dict_column is None.","Re-index the data so all segments include the str dictionary for the field.","Filter out segments/fields lacking a dictionary before precompute_term_ord is called."],"exampleFix":"// before\nlet dict = str_dict_column.as_ref().expect(\"dictionary missing for str accessor\").dictionary();\n// after\nlet dict = str_dict_column.as_ref()\n    .ok_or_else(|| TantivyError::InvalidArgument(format!(\"field '{}' has no str dictionary\", field)))?\n    .dictionary();","handlingStrategy":"validation","validationCode":"// Ensure the field has a str dictionary column before precompute\nif accessor.str_dict_column().is_none() {\n    return Err(TantivyError::InvalidArgument(format!(\n        \"field '{}' has no str dictionary; cannot precompute term ords\", field\n    )));\n}","typeGuard":"fn has_str_dictionary(str_dict_column: &Option<StrColumn>) -> bool {\n    str_dict_column.is_some()\n}","tryCatchPattern":null,"preventionTips":["Index group-by fields as keyword/str with dictionaries","Check schema before running composite aggregation on a field","Re-index segments missing dictionaries","Guard optional dictionary columns with proper error returns instead of expect"],"tags":["rust","panic","aggregation","composite","dictionary"],"backgroundTag":"missing-dictionary-column","analyzedSha":"b5d8deb80c26924e6b007a5b1a7630f35ca64de4","analyzedAt":"2026-09-05T13:20:51.521Z","contentChangedAt":"2026-09-05T13:20:51.521Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}