dbt-labs/dbt-core · error · minijinja::Error::InvalidOperation

parse_columns_and_constraints is only available for…

Error message

parse_columns_and_constraints is only available for Databricks/Spark adapter

What it means

parse_columns_and_constraints parses existing columns plus model constraints into Databricks/Spark constraint syntax, and is explicitly restricted to the Databricks and Spark adapters. Any other adapter type immediately raises an InvalidOperation error before any parsing happens.

Solutions

  1. Only call parse_columns_and_constraints from Databricks or Spark models/macros.
  2. Add an adapter-type guard in your macro with a graceful fallback for other adapters.
  3. Move constraint parsing into adapter-conditional logic if the materialization is shared.
  4. Check the adapter configured in profiles.yml matches what the model's materialization expects.

Example fix

// before
parsed = adapter.parse_columns_and_constraints(existing_columns, model_columns, model_name)

// after
if adapter.type() in ('databricks', 'spark'):
    parsed = adapter.parse_columns_and_constraints(existing_columns, model_columns, model_name)
else:
    parsed = model_columns
Defensive patterns

Strategy: type-guard

Validate before calling

def supports_columns_and_constraints(adapter_type):
    return adapter_type in ('databricks', 'spark')

Type guard

def is_databricks_or_spark(adapter_type):
    return adapter_type in ('databricks', 'spark')

Try / catch

try:
    parsed = adapter.parse_columns_and_constraints(existing, model_columns, name)
except Exception as e:
    if 'Databricks/Spark adapter' in str(e):
        parsed = model_columns  # fallback for other adapters
    else:
        raise

Prevention

When it happens

Trigger: Calling parse_columns_and_constraints while self.adapter_type() is neither Databricks nor Spark — e.g. under Postgres, Snowflake, or BigQuery.

Common situations: Reusing a Databricks custom materialization macro on another warehouse; running a project with mixed adapters where the macro doesn't dispatch on adapter type.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at crates/dbt-adapter/src/adapter/adapter_impl.rs:4643

    ///
    /// Returns [enriched_columns, typed_constraints] for use with get_column_and_constraints_sql
    /// and relation.enrich().
    ///
    /// DatabricksAdapter https://github.com/databricks/dbt-databricks/blob/45351e11517d3f37c5ac7a736b5fcba453d3f368/dbt/adapters/databricks/impl.py#L1038
    pub fn parse_columns_and_constraints(
        &self,
        _state: &State,
        existing_columns: &Value,
        model_columns: &Value,
        model_constraints: &Value,
        contract_enforced: bool,
        model_name: &str,
    ) -> Result<Value, minijinja::Error> {
        use crate::relation::databricks::typed_constraint;
        use std::collections::{BTreeMap, BTreeSet};

        if self.adapter_type() != Databricks && self.adapter_type() != Spark {
            return Err(minijinja::Error::new(
                minijinja::ErrorKind::InvalidOperation,
                "parse_columns_and_constraints is only available for Databricks/Spark adapter",
            ));
        }

        let columns: Vec<Column> = existing_columns
            .try_iter()
            .map_err(|e| {
                minijinja::Error::new(
                    minijinja::ErrorKind::InvalidOperation,
                    format!("existing_columns must be iterable: {e}"),
                )
            })?
            .map(|v| {
                v.downcast_object_ref::<Column>().cloned().ok_or_else(|| {
                    minijinja::Error::new(
                        minijinja::ErrorKind::InvalidOperation,
                        "existing_columns must contain Column objects",

View on GitHub (pinned to 0267ce9170)