influxdata/influxdb · error

We should never receive an unspecified type in a TableBatch

Error message

We should never receive an unspecified type in a TableBatch

What it means

unreachable!("We should never receive an unspecified type in a TableBatch") panic in TableBatch::type_description: the method maps a column's SemanticType to an InfluxColumnType description, and SemanticType::Unspecified is considered invalid for any column inside a TableBatch. Reaching that match arm means schema metadata carried a column whose semantic type was never set.

Solutions

  1. Ensure every column's SemanticType is explicitly set to Tag, Time, or Field when building the TableBatch schema
  2. Validate the schema before constructing the batch, rejecting Unspecified semantic types early
  3. Replace unreachable! with a Result error for resilience against legacy metadata
  4. Check deserialization code for defaulting to SemanticType::Unspecified on missing fields

Example fix

// before
SemanticType::Unspecified => {
    unreachable!("We should never receive an unspecified type in a TableBatch")
}
// after
SemanticType::Unspecified => return Err(SchemaError::UnspecifiedSemanticType),
Defensive patterns

Strategy: validation

Validate before calling

// rust
fn all_semantic_types_set(cols: &[ColumnDef]) -> bool {
    cols.iter().all(|c| c.semantic_type() != SemanticType::Unspecified)
}

Try / catch

match col.semantic_type() {
    SemanticType::Unspecified => return Err(SchemaError::UnspecifiedSemanticType),
    other => /* proceed with other */ (),
}

Prevention

When it happens

Trigger: Constructing a TableBatch whose columns include a field with SemanticType::Unspecified — e.g. schema built without calling the semantic-type inference, deserializing old/partial schema metadata, or a default() derived column that never got a real type.

Common situations: Schema deserialization from older format versions that lacked semantic types, hand-written test schemas using Default::default() for SemanticType, or upstream writers failing to tag columns as Tag/Time/Field.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19). Data as JSON: /api/errors/d46365ab9b0c31e1. Report an issue: GitHub.

Appendix: source

Thrown at core/partition/src/traits.rs:167

                .and_then(|s| s.dictionary.as_ref())
                .map(|dict| {
                    let start =
                        usize::try_from(dict.offsets[usize::try_from(*tag_identity_key).unwrap()])
                            .unwrap();
                    let end = usize::try_from(
                        dict.offsets[usize::try_from(tag_identity_key + 1).unwrap()],
                    )
                    .unwrap();
                    dict.values.split_at(start).1.split_at(end - start).0
                }),
            _ => None,
        }
    }

    fn type_description(&self) -> String {
        match self.semantic_type() {
            SemanticType::Unspecified => {
                unreachable!("We should never receive an unspecified type in a TableBatch")
            }
            SemanticType::Tag => InfluxColumnType::Tag.to_string(),
            SemanticType::Time => InfluxColumnType::Timestamp.to_string(),
            SemanticType::Field => {
                let Values {
                    i64_values,
                    f64_values,
                    u64_values,
                    string_values,
                    bool_values,
                    bytes_values: _,
                    packed_string_values,
                    interned_string_values,
                } = self.values.as_ref().unwrap();

                if !i64_values.is_empty() {
                    InfluxColumnType::Field(schema::InfluxFieldType::Integer).to_string()
                } else if !f64_values.is_empty() {

View on GitHub (pinned to 06200ef96b)