influxdata/influxdb · error
should have gotten a StringArray
Error message
should have gotten a StringArray
What it means
expect("should have gotten a StringArray") panic in get_tag_identity_key: after successfully downcasting to DictionaryArray<Int32Type>, the code downcasts dict.values() to StringArray because the schema promised Utf8 dictionary values. If the dictionary's value array is not a StringArray (e.g. LargeStringArray or BinaryArray), the downcast returns None and expect panics.
Solutions
- Confirm the dictionary's values() array is a StringArray (Utf8) before downcasting
- Handle the None case gracefully: return None or map to an error instead of expect()
- Normalize ingestion so tag dictionaries always use Utf8 value arrays
- Add a schema check that rejects Dictionary types whose values are not Utf8
Example fix
// before
.expect("should have gotten a StringArray");
// after
.ok_or_else(|| TimeColumnError::UnexpectedType("StringArray".into()))?; Defensive patterns
Strategy: type-guard
Validate before calling
// rust
fn dict_values_are_utf8(dict: &DictionaryArray<Int32Type>) -> bool {
dict.values().as_any().downcast_ref::<StringArray>().is_some()
} Type guard
// rust
fn as_string_values<'a>(dict: &'a DictionaryArray<Int32Type>) -> Option<&'a StringArray> {
dict.values().as_any().downcast_ref::<StringArray>()
} Try / catch
let values = dict.values().as_any().downcast_ref::<StringArray>()
.ok_or(TimeColumnError::UnexpectedType("expected Utf8 dictionary values"))?; Prevention
- Reject Dictionary schemas whose value type is not Utf8 at schema validation
- Normalize LargeUtf8/Binary dictionary values to Utf8 during ingestion
- Pin arrow-rs versions to avoid silent default type changes
When it happens
Trigger: A dictionary column whose values are LargeUtf8/Binary/other rather than Utf8, while the schema-level DataType guard matched Dictionary(Int32, Utf8) — i.e. schema and physical value array disagree, or the guard is bypassed by a differently typed value array.
Common situations: Data written by a producer using LargeStringArray-backed dictionaries, arrow-rs upgrades changing default value types, or fixtures building dictionaries with non-string values.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- should have gotten a DictionaryArray
- time column was an unexpected type
- Unsupported InfluxQL data type
- column id in series key should be valid
- duration not to overflow
AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19).
Data as JSON: /api/errors/cbaf0adffaccd1c0.
Report an issue: GitHub.
Appendix: source
Thrown at core/partition/src/traits/record_batch.rs:36
debug_assert!(PartitioningColumn::is_valid(self, idx));
match self.data_type() {
DataType::Utf8 => self
.as_any()
.downcast_ref::<StringArray>()
.map(|col_data| col_data.value(idx)),
DataType::Dictionary(key, value)
if key.as_ref() == &DataType::Int32 && value.as_ref() == &DataType::Utf8 =>
{
let dict = self
.as_any()
.downcast_ref::<DictionaryArray<Int32Type>>()
.expect("should have gotten a DictionaryArray");
let values = dict
.values()
.as_any()
.downcast_ref::<StringArray>()
.expect("should have gotten a StringArray");
Some(values.value(dict.key(idx)?))
}
_ => None,
}
}
fn get_tag_value<'a>(&'a self, tag_identity_key: &'a Self::TagIdentityKey) -> Option<&'a str> {
Some(tag_identity_key)
}
fn type_description(&self) -> String {
self.data_type().to_string()
}
}
impl Batch for RecordBatch {
type Column = Arc<dyn Array>;
View on GitHub (pinned to 06200ef96b)