influxdata/influxdb · error

By the point that we're doing partitioning, we should've…

Error message

By the point that we're doing partitioning, we should've already verified that we have values for each column that we want to partition

What it means

This unreachable!() panic fires in the schema `type_description` logic when a column has no string values (plain, packed, or interned) at the time partitioning metadata is computed. The code assumes earlier validation guaranteed values exist for every partition-relevant column; if the assumption breaks, it panics instead of returning an error. It is an internal invariant violation, not an expected user-facing error.

Solutions

  1. Check the input batches: ensure every column intended for partitioning has at least one non-null value before invoking type_description/partitioning
  2. Verify the column is actually a tag or String field; time/int columns take different branches and never reach this panic
  3. Trace where the earlier 'verified values for each column' step was skipped or reordered and restore it
  4. Upgrade/align versions of the schema/partition crates so the pre-validation invariant matches the type_description implementation

Example fix

// before: panics on empty string columns
let desc = col_type.to_string();
// after: validate before partitioning
assert!(
    !string_values.is_empty()
        || packed_string_values.is_some()
        || interned_string_values.is_some(),
    "column {} has no values for partitioning",
    col_name
);
Defensive patterns

Strategy: validation

Validate before calling

fn has_partition_values(col: &ColumnSummary) -> bool {
    col.string_values_count > 0
        || col.packed_string_values.is_some()
        || col.interned_string_values.is_some()
}
if !has_partition_values(&summary) { return Err(anyhow!("column {} lacks values for partitioning", summary.name)); }

Type guard

fn is_partitionable(col: &ColumnSummary) -> bool {
    matches!(col.data_type, InfluxColumnType::Tag | InfluxColumnType::Field(InfluxFieldType::String))
        && col.string_values_count > 0
}

Prevention

When it happens

Trigger: Calling the InfluxColumnType/type_description path for a column that is neither a time nor tag column and whose String field values are entirely absent — e.g. schema derived from a record batch where a String field column is empty, all-null, or was dropped before partitioning.

Common situations: Feeding parquet/batches with missing or all-null string field columns into the partitioner; version drift where upstream code no longer pre-validates columns; custom ingestion paths that skip the earlier verification step the invariant assumes.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

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

                    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() {
                    InfluxColumnType::Field(schema::InfluxFieldType::Float).to_string()
                } else if !u64_values.is_empty() {
                    InfluxColumnType::Field(schema::InfluxFieldType::UInteger).to_string()
                } else if !bool_values.is_empty() {
                    InfluxColumnType::Field(schema::InfluxFieldType::Boolean).to_string()
                } else if !string_values.is_empty()
                    || packed_string_values.is_some()
                    || interned_string_values.is_some()
                {
                    InfluxColumnType::Field(schema::InfluxFieldType::String).to_string()
                } else {
                    unreachable!(
                        "By the point that we're doing partitioning, we should've already verified that we have values for each column that we want to partition"
                    )
                }
            }
        }
    }
}

impl Batch for TableBatchWithoutId {
    type Column = proto::Column;

    fn num_rows(&self) -> usize {
        self.row_count.try_into().unwrap()
    }

    fn column(&self, column: &str) -> Option<&Self::Column> {
        self.columns.iter().find(|c| c.column_name == column)
    }

View on GitHub (pinned to 06200ef96b)