dbt-labs/dbt-core · error

when data_type is date, inner must be a TimeConfig

Error message

when data_type is date, inner must be a TimeConfig

What it means

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.

Source

Thrown at crates/dbt-schemas/src/schemas/manifest/bigquery_partition.rs:211

            Ok(MinijinjaValue::from(columns))
        } else {
            Err(MinijinjaError::new(
                MinijinjaErrorKind::InvalidArgument,
                "columns must be a list of Column",
            ))
        }
    }

    /// Return true if the data type should be truncated instead of cast to the data type
    pub fn data_type_should_be_truncated(&self) -> bool {
        !(self.data_type == "int64"
            || (self.data_type == "date"
                && match &self.__inner__ {
                    BigqueryPartitionConfigInner::Time(TimeConfig { granularity, .. }) => {
                        granularity == "day"
                    }
                    BigqueryPartitionConfigInner::Range(_) => {
                        unreachable!("when data_type is date, inner must be a TimeConfig")
                    }
                }))
    }

    /// Return the time partitioning field name based on the data type.
    /// The default is _PARTITIONTIME, but for date it is _PARTITIONDATE
    pub fn time_partitioning_field(&self) -> Result<MinijinjaValue, MinijinjaError> {
        let field = if self.data_type == "date" {
            Self::PARTITION_DATE
        } else {
            Self::PARTITION_TIME
        };
        Ok(MinijinjaValue::from(field))
    }

    /// Return the insertable time partitioning field name based on the data type.
    /// Practically, only _PARTITIONTIME works so far.
    pub fn insertable_time_partitioning_field(&self) -> Result<MinijinjaValue, MinijinjaError> {

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Fix the config so that data_type "date" pairs with the Time inner variant and granularity "day".
  2. Ensure configs go through the serde deserializer/validation path instead of being constructed field-by-field in code.
  3. If building configs programmatically, use the constructor that derives __inner__ from data_type rather than setting both independently.
  4. Check for version skew: older serialized manifests may encode a shape the current code considers impossible; re-deserialize with the matching schema version.

Example fix

// before (invalid config)
BigqueryPartitionConfig { data_type: "date".into(), __inner__: BigqueryPartitionConfigInner::Range(range_cfg), .. }

// after
BigqueryPartitionConfig { data_type: "date".into(), __inner__: BigqueryPartitionConfigInner::Time(TimeConfig { granularity: "day".into(), ..Default::default() }), .. }
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_partition(cfg: &BigqueryPartitionConfig) -> bool {
    !(cfg.data_type == "date" && matches!(cfg.__inner__, BigqueryPartitionConfigInner::Range(_)))
}

Type guard

fn as_time_inner(inner: &BigqueryPartitionConfigInner) -> Option<&TimeConfig> {
    match inner { BigqueryPartitionConfigInner::Time(t) => Some(t), _ => None }
}

Prevention

When it happens

Trigger: Calling data_type_should_be_truncated (directly or via render/render_wrapped) on a BigqueryPartitionConfig whose __inner__ is BigqueryPartitionConfigInner::Range while data_type == "date".

Common situations: 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.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07). Data as JSON: /api/errors/a09f4fbdccf5a001. Report an issue: GitHub.