dbt-labs/dbt-core · warning
Constraint of type {{ type }} with no `name` provided. Gener
Error message
Constraint of type {{ type }} with no `name` provided. Generating hash instead for relation {{ relation.identifier }} What it means
Like error 787 but on the foreign_key-with-expression path: when a foreign_key constraint supplies an `expression` (e.g. `(id) references parent(id)`) but no `name`, and `local_md5` is available, the macro warns and generates the constraint name as `md5("foreign_key;<identifier>;<expression>;")`. Without md5 it would instead raise a compiler error; here compilation succeeds with a hash name.
Source
Thrown at crates/dbt-loader/src/dbt_macro_assets/dbt-databricks/macros/relations/constraints.sql:233
{{ exceptions.raise_compiler_error("Constraint of type " ~ type ~ " with no `name` provided, and no md5 utility.") }}
{% endif %}
{% endif %}
{% set pk_suffix = (" " ~ pk_expression) if pk_expression else "" %}
{% set stmt = "alter table " ~ relation.render() ~ " add constraint " ~ name ~ " primary key(" ~ joined_names ~ ")" ~ pk_suffix ~ ";" %}
{% do statements.append(stmt) %}
{% elif type == 'foreign_key' %}
{% if constraint.get('warn_unenforced') %}
{{ exceptions.warn("unenforced constraint type: " ~ constraint.type)}}
{% endif %}
{% set name = constraint.get('name') %}
{% if constraint.get('expression') %}
{% if not name %}
{% if local_md5 %}
{{ exceptions.warn("Constraint of type " ~ type ~ " with no `name` provided. Generating hash instead for relation " ~ relation.identifier) }}
{%- set name = local_md5("foreign_key;" ~ relation.identifier ~ ";" ~ constraint.get('expression') ~ ";") -%}
{% else %}
{{ exceptions.raise_compiler_error("Constraint of type " ~ type ~ " with no `name` provided, and no md5 utility.") }}
{% endif %}
{% endif %}
{% set stmt = "alter table " ~ relation.render() ~ " add constraint " ~ name ~ " foreign key" ~ constraint.get('expression') %}
{% else %}
{% set column_names = constraint.get('columns', []) %}
{% if column and not column_names %}
{% set column_names = [column['name']] %}
{% endif %}
{% set quoted_names = [] %}
{% for column_name in column_names %}
{% set column = model.get('columns', {}).get(column_name) %}
{% if not column %}
{{ exceptions.warn('Invalid foreign key column: ' ~ column_name) }}
{% else %}View on GitHub (pinned to 0267ce9170)
Solutions
- Add an explicit `name` field to the foreign_key constraint for a stable, readable name.
- Accept the warning; the md5-derived name is deterministic for identical identifier+expression.
- If the generated name changes when the expression is edited, pin a `name` to keep the constraint identity stable across refactors.
- Ensure the adapter exposes local_md5 — if it is missing this same condition raises a compiler error instead.
Example fix
// before - type: foreign_key expression: "(user_id) REFERENCES parent(id)" // after - type: foreign_key name: fk_child_user expression: "(user_id) REFERENCES parent(id)"
Defensive patterns
Strategy: validation
Validate before calling
import yaml
cfg = yaml.safe_load(open('models/schema.yml'))
for m in cfg['models']:
for c in m.get('constraints', []):
if c['type'] == 'foreign_key' and c.get('expression') and not c.get('name'):
raise ValueError(f"foreign_key constraint on {m['name']} needs a name") Type guard
def fk_is_named(c: dict) -> bool:
return not c.get('expression') or bool(c.get('name')) Prevention
- Pair every foreign_key expression with an explicit name.
- Lint schema.yml in CI to reject unnamed constraints.
- Pin names to survive expression refactors without constraint identity churn.
- Verify the adapter provides local_md5, otherwise this becomes a compiler error.
When it happens
Trigger: A foreign_key constraint with `expression` set but `name` omitted, processed at constraints.sql:231-234 while `local_md5` exists; e.g. `constraints: [{type: foreign_key, expression: "(user_id) REFERENCES schema.parent(id)"}]`.
Common situations: Hand-written FK expressions copied from DDL without names; dbt-codegen or migration tooling emitting expression-only constraints; older dbt versions that did not require `name` on constraints.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- unenforced constraint type: {constraint.type}
- unenforced constraint type: {type}
- Invalid primary key column: {column_name}
- Invalid foreign key column: {{ column_name }}
- Constraints not supported for file format: {adapter.resolve_
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/05a061a9b1a0a50c.
Report an issue: GitHub.