Metacenta

Lineage integrity · rule hardcoded-table-reference

dbt models with a hardcoded table name

A Metacenta review checks this under the rule Models reach inputs through ref() / source(). Everything below applies whether or not you ever commission one.

What this rule checks

This rule flags dbt models whose SQL reads a schema-qualified relation, such as analytics.orders, instead of using ref() or source(). A templated schema with a literal table name, such as {{ target.schema }}.orders, is flagged too. A bare table name with no schema is not. CTE names, table aliases and system catalogues such as information_schema are excluded.

Why it matters

dbt cannot see the dependency, so its DAG is wrong. The model can build before its input, and the reference does not follow the target schema between development and production.

How to fix it

Replace hardcoded table names so the build order is known. Replace the literal relation with {{ ref() }} when dbt builds it. When something outside dbt loads it, declare it as a source and read it with {{ source() }}.

Before:

select order_id, customer_id, ordered_at
from raw_shop.orders

After:

select order_id, customer_id, ordered_at
from {{ source('shop', 'orders') }}

When it is fine to leave

A warehouse metadata or audit view outside the catalogues we recognise is not a lineage break, since nothing in the project builds it. Declaring it as a source still records where it comes from. A one-off model due for deletion can also stay as it is.

What we need to check it

manifest.json, with the raw_code each model carries. If no model carries it, the rule declines. We read the Jinja-templated SQL as text rather than compiling it, so the finding is medium confidence.

Published rules it corresponds to

dbt_project_evaluator, rule fct_hard_coded_references. Ours checks the same condition and threshold.

This means our check corresponds to their rule. It does not mean the publisher reviewed or endorses it.