{"record":{"id":"a09f4fbdccf5a001","repo":"dbt-labs/dbt-core","slug":"when-data-type-is-date-inner-must-be-a-timeconfig","errorCode":null,"errorMessage":"when data_type is date, inner must be a TimeConfig","messagePattern":"when data_type is date, inner must be a TimeConfig","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/dbt-schemas/src/schemas/manifest/bigquery_partition.rs","lineNumber":211,"sourceCode":"            Ok(MinijinjaValue::from(columns))\n        } else {\n            Err(MinijinjaError::new(\n                MinijinjaErrorKind::InvalidArgument,\n                \"columns must be a list of Column\",\n            ))\n        }\n    }\n\n    /// Return true if the data type should be truncated instead of cast to the data type\n    pub fn data_type_should_be_truncated(&self) -> bool {\n        !(self.data_type == \"int64\"\n            || (self.data_type == \"date\"\n                && match &self.__inner__ {\n                    BigqueryPartitionConfigInner::Time(TimeConfig { granularity, .. }) => {\n                        granularity == \"day\"\n                    }\n                    BigqueryPartitionConfigInner::Range(_) => {\n                        unreachable!(\"when data_type is date, inner must be a TimeConfig\")\n                    }\n                }))\n    }\n\n    /// Return the time partitioning field name based on the data type.\n    /// The default is _PARTITIONTIME, but for date it is _PARTITIONDATE\n    pub fn time_partitioning_field(&self) -> Result<MinijinjaValue, MinijinjaError> {\n        let field = if self.data_type == \"date\" {\n            Self::PARTITION_DATE\n        } else {\n            Self::PARTITION_TIME\n        };\n        Ok(MinijinjaValue::from(field))\n    }\n\n    /// Return the insertable time partitioning field name based on the data type.\n    /// Practically, only _PARTITIONTIME works so far.\n    pub fn insertable_time_partitioning_field(&self) -> Result<MinijinjaValue, MinijinjaError> {","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-schemas/src/schemas/manifest/bigquery_partition.rs#L193-L229","documentation":"This panic fires inside BigQuery partition config logic when a partition whose data_type is \"date\" is backed by a Range config instead of a Time config. The library treats that combination as logically impossible: data_type \"date\" is only meaningful for time-based partitioning with day granularity, so the match arm for Range is marked unreachable. Reaching it means an inconsistent BigqueryPartitionConfig was constructed without being validated.","triggerScenarios":"Calling data_type_should_be_truncated (directly or via render/render_wrapped) on a BigqueryPartitionConfig whose __inner__ is BigqueryPartitionConfigInner::Range while data_type == \"date\".","commonSituations":"Hand-constructing a BigqueryPartitionConfig from deserialized dbt config where data_type and the inner variant were set independently (e.g. a user's yml sets `partition_by: {type: date}` but the config was normalized into a range partition), or bypassing serde validation when programmatically building configs.","solutions":["Fix the config so that data_type \"date\" pairs with the Time inner variant and granularity \"day\".","Ensure configs go through the serde deserializer/validation path instead of being constructed field-by-field in code.","If building configs programmatically, use the constructor that derives __inner__ from data_type rather than setting both independently.","Check for version skew: older serialized manifests may encode a shape the current code considers impossible; re-deserialize with the matching schema version."],"exampleFix":"// before (invalid config)\nBigqueryPartitionConfig { data_type: \"date\".into(), __inner__: BigqueryPartitionConfigInner::Range(range_cfg), .. }\n\n// after\nBigqueryPartitionConfig { data_type: \"date\".into(), __inner__: BigqueryPartitionConfigInner::Time(TimeConfig { granularity: \"day\".into(), ..Default::default() }), .. }","handlingStrategy":"validation","validationCode":"fn is_valid_partition(cfg: &BigqueryPartitionConfig) -> bool {\n    !(cfg.data_type == \"date\" && matches!(cfg.__inner__, BigqueryPartitionConfigInner::Range(_)))\n}","typeGuard":"fn as_time_inner(inner: &BigqueryPartitionConfigInner) -> Option<&TimeConfig> {\n    match inner { BigqueryPartitionConfigInner::Time(t) => Some(t), _ => None }\n}","tryCatchPattern":null,"preventionTips":["Always build BigQuery partition configs through serde/validation, not field-by-field.","Keep data_type and the inner variant derived from a single source of truth.","Add a unit test covering data_type=date with each inner variant."],"tags":["bigquery","partitioning","config","unreachable","rust"],"backgroundTag":"invalid-config-value","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}