Adovo

Data & Analytics

A dbt model contract can miss a breaking change inside STRUCT

A nested field type change may pass a model-version breaking-change check. Compare normalized schemas and downstream behavior before release.

October 27, 2026

A model version passes a contract check, then a consumer fails because a nested value changed type. A recent dbt-core issue reproduces this with STRUCT(a INTEGER) becoming STRUCT(a VARCHAR) and a Nullable type change. In the reported version, the breaking-change comparison normalizes away the parameterized detail. This is a specific open issue, not proof that every adapter or contract check behaves the same way.

Identify the boundary of the contract

List the fields whose exact nested structure is part of the consumer promise. Review dbt's model contract configuration and model version properties for the behavior your project relies on. A successful dbt build confirms the version's declared shape under its checks; it may not prove that a new version preserves every nested subtype from the old version.

Add a comparison where consumers can break

Before promotion, capture the compiled or warehouse-resolved schemas of old and new model versions. Compare nested fields recursively, including nullability and precision, and classify any differences with consumer owners. Run a representative query from each critical downstream model or dashboard. This is particularly useful for arrays of structs and platform-specific types whose human-readable names hide parameters.

Release with evidence

If the nested type must change, publish it as an intentional versioned interface and give consumers a migration path. If it should not change, block release until the query and declaration agree. Keep the dbt-core issue pinned in the engineering record and retest the minimal reproduction after a future upgrade; do not remove the extra check merely because a release note sounds related.

Adovo’s view

A contract is valuable only at the depth where a customer or system depends on it. A green build is evidence about the check that ran, not a promise about details the check did not inspect.

Continue exploring

Data & Analytics

dbtMicrobatch

A dbt microbatch rebuild fails before it can repair history

A reported dbt v2 parser error can block a microbatch full refresh. Protect the recovery path before changing a production model.

Read more

Data & Analytics

DatabricksDelta Lake

Before changing a Delta table schema, find the consumers your lineage misses

Observed lineage is useful, but it can miss infrequent or external consumers. Combine it with declared contracts before renaming or removing a Delta column.

Read more

Data & Analytics

dbtSource freshness

dbt build is green while source data is stale: put freshness before the model

Passing transformations do not prove new source data arrived. Add an explicit freshness decision and a named owner for the ingestion-to-dbt handoff.

Read more
Explore data and analytics services →