{"record":{"id":"62717a3851b4be1b","repo":"influxdata/influxdb","slug":"should-have-gotten-a-dictionaryarray","errorCode":null,"errorMessage":"should have gotten a DictionaryArray","messagePattern":"should have gotten a DictionaryArray","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/partition/src/traits/record_batch.rs","lineNumber":30,"sourceCode":"\n    fn is_valid(&self, idx: usize) -> bool {\n        Array::is_valid(&self, idx)\n    }\n\n    fn get_tag_identity_key(&self, idx: usize) -> Option<&Self::TagIdentityKey> {\n        debug_assert!(PartitioningColumn::is_valid(self, idx));\n        match self.data_type() {\n            DataType::Utf8 => self\n                .as_any()\n                .downcast_ref::<StringArray>()\n                .map(|col_data| col_data.value(idx)),\n            DataType::Dictionary(key, value)\n                if key.as_ref() == &DataType::Int32 && value.as_ref() == &DataType::Utf8 =>\n            {\n                let dict = self\n                    .as_any()\n                    .downcast_ref::<DictionaryArray<Int32Type>>()\n                    .expect(\"should have gotten a DictionaryArray\");\n\n                let values = dict\n                    .values()\n                    .as_any()\n                    .downcast_ref::<StringArray>()\n                    .expect(\"should have gotten a StringArray\");\n                Some(values.value(dict.key(idx)?))\n            }\n            _ => None,\n        }\n    }\n\n    fn get_tag_value<'a>(&'a self, tag_identity_key: &'a Self::TagIdentityKey) -> Option<&'a str> {\n        Some(tag_identity_key)\n    }\n\n    fn type_description(&self) -> String {\n        self.data_type().to_string()","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/core/partition/src/traits/record_batch.rs#L12-L48","documentation":"expect(\"should have gotten a DictionaryArray\") panic in get_tag_identity_key: the guard already matched DataType::Dictionary(Int32, Utf8) on the column's logical type, so the code assumes as_any().downcast_ref::<DictionaryArray<Int32Type>>() must succeed. It panics when the physical array is not actually an Int32-keyed DictionaryArray despite the reported datatype.","triggerScenarios":"Calling get_tag_identity_key on a tag column whose DataType reports Dictionary(Int32, Utf8) but whose underlying Arc<dyn Array> is a differently keyed dictionary (e.g. Int8/Int16/UInt keys) or a non-dictionary array due to a mislabeled field/schema.","commonSituations":"Arrow/upstream producers emitting dictionaries with non-Int32 keys while the schema claims Int32, or hand-built test arrays with mismatched key types, or an arrow-rs version change in dictionary key defaults.","solutions":["Verify the actual arrow array key type matches Int32 before downcasting (check dict.key_type())","Use downcast_ref and map the None case to a Result/None instead of expect()","Align the schema DataType with the physical array: rebuild the dictionary with DictionaryArray::<Int32Type>","Check the arrow-rs version; dictionary key inference defaults changed across versions"],"exampleFix":"// before\n.expect(\"should have gotten a DictionaryArray\")\n// after\n.ok_or_else(|| TimeColumnError::UnexpectedType(\"DictionaryArray<Int32>\".into()))?","handlingStrategy":"type-guard","validationCode":"// rust\nlet key_is_i32 = matches!(col.data_type(), DataType::Dictionary(k, _) if **k == DataType::Int32);","typeGuard":"// rust\nfn as_i32_dict<'a>(a: &'a dyn Array) -> Option<&'a DictionaryArray<Int32Type>> {\n    a.as_any().downcast_ref::<DictionaryArray<Int32Type>>()\n}","tryCatchPattern":"let dict = col.as_any().downcast_ref::<DictionaryArray<Int32Type>>()\n    .ok_or(TimeColumnError::UnexpectedType(\"expected Int32 dictionary\"))?;","preventionTips":["Verify physical array key types agree with schema DataTypes before downcasting","Normalize all tag dictionaries to Int32 keys at ingestion","Avoid expect() on downcasts of externally produced arrow arrays"],"tags":["rust","panic","downcast","arrow","dictionary-array"],"backgroundTag":"type-mismatch","analyzedSha":"06200ef96ba82c5f6727e5038a83af8e722c6875","analyzedAt":"2026-09-19T12:55:30.003Z","contentChangedAt":"2026-09-19T12:55:30.003Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}