{"record":{"id":"ac19e5207d90b692","repo":"dbt-labs/dbt-core","slug":"contract-enforced-true-on-materialized-view-mo","errorCode":null,"errorMessage":"contract.enforced=true on materialized_view '{{ model.name }}': not supported by dbt (https://docs.getdbt.com/docs/mesh/govern/model-contracts). dbt-databricks provides best-effort support that may change without notice.","messagePattern":"contract\\.enforced=true on materialized_view '(.+?)\\}': not supported by dbt \\(https://docs\\.getdbt\\.com/docs/mesh/govern/model-contracts\\)\\. dbt-databricks provides best-effort support that may change without notice\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/dbt-loader/src/dbt_macro_assets/dbt-databricks/macros/relations/materialized_view/create.sql","lineNumber":32,"sourceCode":"  {# DIVERGENCE END #}\n\n  {#\n    TODO: When DESCRIBE QUERY EXTENDED is supported, this implementation should be simplified\n    to use that instead. For now, we work around this limitation by writing results to a\n    temporary view and using DESCRIBE TABLE EXTENDED on the temporary view.\n  #}\n  {%- set temp_relation = make_temp_relation(relation) -%}\n  {% call statement('create_temp_view') -%}\n    {%- set sql_with_limit = sql.rstrip('; \\n\\t') ~ ' LIMIT 10' -%}\n    {{ create_temporary_view(temp_relation, sql_with_limit) }}\n  {%- endcall %}\n\n  {%- set columns = adapter.get_columns_in_relation(temp_relation) -%}\n  {%- set model_columns = model.get('columns', {}) -%}\n  {%- set contract_config = config.get('contract') -%}\n  {%- set contract_enforced = contract_config and contract_config.enforced -%}\n  {%- if contract_enforced -%}\n    {%- do exceptions.warn(\n         \"contract.enforced=true on materialized_view '\" ~ model.name ~ \"': not supported by dbt (https://docs.getdbt.com/docs/mesh/govern/model-contracts). dbt-databricks provides best-effort support that may change without notice.\"\n       ) -%}\n    {%- set model_constraints = model.get('constraints', []) -%}\n  {%- else -%}\n    {%- set model_constraints = [] -%}\n  {%- endif -%}\n  {%- set columns_and_constraints = adapter.parse_columns_and_constraints(columns, model_columns, model_constraints, contract_enforced, model.name) -%}\n  {%- set target_relation = relation.enrich(columns_and_constraints[1]) -%}\n\n  create or replace materialized view {{ target_relation.render() }}\n    {{ get_column_and_constraints_sql(target_relation, columns_and_constraints[0]) }}\n    {{ get_create_row_filter_clause(target_relation) }}\n    {{ get_create_sql_partition_by(partition_by) }}\n    {{ liquid_clustered_cols() }}\n    {{ get_create_sql_comment(comment) }}\n    {{ get_create_sql_tblproperties(tblproperties) }}\n    {{ get_create_sql_refresh_schedule(refresh.cron, refresh.time_zone_value) }}\n  as","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-loader/src/dbt_macro_assets/dbt-databricks/macros/relations/materialized_view/create.sql#L14-L50","documentation":"dbt core does not support model contracts on materialized views. When a dbt-databricks materialized view has `contract.enforced: true`, the adapter warns that its contract support is best-effort and may change, then still reads model constraints/columns to build the view. It is a heads-up that contract behavior here is non-standard and unprotected by core guarantees.","triggerScenarios":"A materialized view model sets `config.contract.enforced=true` (via YAML config or `{{ config(...) }}`) and is built with dbt-databricks.","commonSituations":"Applying a shared `contract` config block across all models including MVs; adopting contracts for governance and applying them uniformly; copy-pasted model configs from table models.","solutions":["Remove `contract.enforced` (or set it false) for materialized_view models","Scope the contract config to supported materializations only (tables/views) via `config` selectors or per-model YAML","If you rely on it, pin dbt-databricks versions and re-validate MV contract behavior on upgrades"],"exampleFix":"# before\nmodels:\n  - name: my_mv\n    config:\n      materialized: materialized_view\n      contract:\n        enforced: true\n# after\nmodels:\n  - name: my_mv\n    config:\n      materialized: materialized_view\n# keep contracts on table models only","handlingStrategy":"validation","validationCode":"def check_contract_on_mv(model):\n    if model.get('config', {}).get('materialized') == 'materialized_view':\n        assert not model.get('config', {}).get('contract', {}).get('enforced'), \\\n            f\"{model['name']}: contract.enforced not supported on materialized_view\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Scope contract configs to table/view materializations only","Avoid blanket `+contract:` config inheritance onto materialized views","Review the dbt core contract support matrix per materialization","Treat the warning as a prompt to remove the config, not to ignore it"],"tags":["databricks","materialized-view","contract","jinja"],"backgroundTag":"feature-not-enabled","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}