{"record":{"id":"b29c512da7cce5d2","repo":"influxdata/influxdb","slug":"by-the-point-that-we-re-doing-partitioning-we-should-ve","errorCode":null,"errorMessage":"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","messagePattern":"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","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/partition/src/traits.rs","lineNumber":197,"sourceCode":"                    packed_string_values,\n                    interned_string_values,\n                } = self.values.as_ref().unwrap();\n\n                if !i64_values.is_empty() {\n                    InfluxColumnType::Field(schema::InfluxFieldType::Integer).to_string()\n                } else if !f64_values.is_empty() {\n                    InfluxColumnType::Field(schema::InfluxFieldType::Float).to_string()\n                } else if !u64_values.is_empty() {\n                    InfluxColumnType::Field(schema::InfluxFieldType::UInteger).to_string()\n                } else if !bool_values.is_empty() {\n                    InfluxColumnType::Field(schema::InfluxFieldType::Boolean).to_string()\n                } else if !string_values.is_empty()\n                    || packed_string_values.is_some()\n                    || interned_string_values.is_some()\n                {\n                    InfluxColumnType::Field(schema::InfluxFieldType::String).to_string()\n                } else {\n                    unreachable!(\n                        \"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\"\n                    )\n                }\n            }\n        }\n    }\n}\n\nimpl Batch for TableBatchWithoutId {\n    type Column = proto::Column;\n\n    fn num_rows(&self) -> usize {\n        self.row_count.try_into().unwrap()\n    }\n\n    fn column(&self, column: &str) -> Option<&Self::Column> {\n        self.columns.iter().find(|c| c.column_name == column)\n    }","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/core/partition/src/traits.rs#L179-L215","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the input batches: ensure every column intended for partitioning has at least one non-null value before invoking type_description/partitioning","Verify the column is actually a tag or String field; time/int columns take different branches and never reach this panic","Trace where the earlier 'verified values for each column' step was skipped or reordered and restore it","Upgrade/align versions of the schema/partition crates so the pre-validation invariant matches the type_description implementation"],"exampleFix":"// before: panics on empty string columns\nlet desc = col_type.to_string();\n// after: validate before partitioning\nassert!(\n    !string_values.is_empty()\n        || packed_string_values.is_some()\n        || interned_string_values.is_some(),\n    \"column {} has no values for partitioning\",\n    col_name\n);","handlingStrategy":"validation","validationCode":"fn has_partition_values(col: &ColumnSummary) -> bool {\n    col.string_values_count > 0\n        || col.packed_string_values.is_some()\n        || col.interned_string_values.is_some()\n}\nif !has_partition_values(&summary) { return Err(anyhow!(\"column {} lacks values for partitioning\", summary.name)); }","typeGuard":"fn is_partitionable(col: &ColumnSummary) -> bool {\n    matches!(col.data_type, InfluxColumnType::Tag | InfluxColumnType::Field(InfluxFieldType::String))\n        && col.string_values_count > 0\n}","tryCatchPattern":null,"preventionTips":["Validate record batches for null/missing partition columns before partitioning","Ensure only tags and String fields reach the partition-column classification path","Pin aligned versions of schema/partition crates so pre-validation invariants hold","Prefer returning Result over unreachable! in code paths fed by external data"],"tags":["panic","invariant","partitioning","schema"],"backgroundTag":"internal-invariant-violation","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"}