Working With Dbt Mesh
Use when changing a dbt model in a way that could break its consumers — renaming, removing, or retyping a column, or changing a model that downstream models, exposures, dashboards, or BI tools depend on — to judge whether the change is breaking and who it affects. Also use when versioning a model (model versions, latest_version, latest_version_pointer, deprecation_date, migration windows), enforcing contracts, setting access or groups, or doing multi-project dbt Mesh work (cross-project refs via dependencies.yml, disambiguating similarly-named models, splitting a monolith). Covers single- and multi-project, and planning or advising as well as implementing.
- Skill ID
- dbt-labs/dbt-agent-skills/working-with-dbt-mesh
- Publisher
- dbt-labs
- Repository
- dbt-agent-skills
- Installs
- 0
- Files
- 5
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
dbt-labs/dbt-agent-skills/working-with-dbt-meshInstalls these files- SKILL.md
- references/cross-project-collaboration.md
- references/groups-and-access.md
- references/model-contracts.md
- references/model-versions.md
What this skill tells the agent
Working with dbt Mesh
Core principle: In a mesh project, upstream data comes through ref(), not source(). Every cross-project reference requires the project name. When in doubt, read dependencies.yml first.
When to Use
- Making a potentially breaking change to a model — renaming, removing, or retyping a column — especially when other models, exposures, or BI tools depend on it. Assess the blast radius before changing it, and reach for model versions rather than editing in place.
- Versioning a model (
versions:,latest_version,latest_version_pointer,deprecation_date) — this applies in a single project, not just multi-project setups - Working in a dbt project that references models from other dbt projects
- Resolving ambiguity when multiple upstream projects have similarly-named models (e.g. multiple
stg_models) - Adding model contracts, access modifiers, or groups
- Setting up cross-project references with
dependencies.yml - Splitting a monolithic dbt project into multiple mesh projects
Do NOT use for:
- General model building or debugging (use the
using-dbt-for-analytics-engineeringskill) - Unit testing models (use the
adding-dbt-unit-testskill) - Semantic layer work (use the
building-dbt-semantic-layerskill)
First: Orient Yourself in a Multi-Project Setup
Before writing or modifying any SQL in a project that uses dbt Mesh, follow these steps:
1. Read dependencies.yml
This file at the project root tells you which upstream projects exist:
# dependencies.yml
projects:
- name: core_platform
- name: marketing_platformIf this file has a projects: key, you are in a multi-project mesh setup. Every model you reference from those upstream projects must use cross-project ref().
2. Understand how upstream data gets into this project
In a mesh setup, upstream project models replace what would alternatively be sources:
| Alternative | Mesh multi-project |
|---|---|
{{ source('stripe', 'payments') }} | {{ ref('core_platform', 'stg_payments') }} |
| Data comes from raw database tables | Data comes from another dbt project's public models |
Defined in sources.yml | Declared in dependencies.yml |
The upstream project has already staged and transformed the raw data. Your project builds on top of their public models, not their raw sources.
3. Disambiguate similarly-named models
When multiple upstream projects have models with the same name (e.g. stg_customers in both core_platform and marketing_platform), you must use the two-argument ref():
-- Correct: explicit project name, no ambiguity
select * from {{ ref('core_platform', 'stg_customers') }}
select * from {{ ref('marketing_platform', 'stg_customers') }}
-- WRONG: dbt cannot determine which project's stg_customers you mean
select * from {{ ref('stg_customers') }}4. Check existing patterns in the codebase
Before writing new SQL:
- Search for existing two-argument
ref()calls to see which upstream projects and models are already in use - Look at the upstream project's YAML for
access: publicmodels — only these are referenceable cross-project - The first argument of
ref()must exactly match thenamefield in the upstream project'sdbt_project.yml(case-sensitive)
5. Know what you can and cannot reference
| Upstream model access | Can you ref() it cross-project? |
|---|---|
access: public | Yes |
access: protected (default) | No — only within the same project |
access: private | No — only within the same group |
If you need a model that isn't public, coordinate with the upstream team to widen its access.
Cross-Project Refs Require dbt Cloud Enterprise
Cross-project ref() and the projects: key in dependencies.yml are only available on dbt Cloud Enterprise or Enterprise+ plans. Before setting up any cross-project collaboration, verify plan eligibility:
- If `dependencies.yml` already has a `projects:` key and the project is actively using cross-project refs — Enterprise is already in place. Proceed.
- Otherwise — ask the user to confirm they are on dbt Cloud Enterprise or Enterprise+ before adding
projects:todependencies.ymlor writing new two-argumentref()calls.
If the user cannot confirm the plan level, or confirms they are on a plan below Enterprise, do not set up cross-project refs. Explain that this feature requires upgrading to Enterprise or Enterprise+ and suggest they use the intra-project governance features (groups, access modifiers, contracts) instead.
Cross-Project ref() Syntax
-- Reference an upstream model (latest version)
select * from {{ ref('upstream_project', 'model_name') }}
-- Reference a specific version
select * from {{ ref('upstream_project', 'model_name', v=2) }}For full cross-project setup details (dependencies.yml, prerequisites, orchestration), see references/cross-project-collaboration.md.
Governance Features
dbt Mesh includes four governance features. These work independently and can be adopted incrementally:
| Feature | Purpose | Key Config | Reference |
|---|---|---|---|
| Model Contracts | Guarantee column names, types, and constraints at build time | contract: {enforced: true} | references/model-contracts.md |
| Groups | Organize models by team/domain ownership | group: finance | references/groups-and-access.md |
| Access Modifiers | Control which models can ref yours | access: public / protected / private | references/groups-and-access.md |
| Model Versions | Manage breaking changes with migration windows | versions: with latest_version: and latest_version_pointer (v1.12+) | references/model-versions.md |
YAML placement rule
In model property YAML files, access, group, and contract are configs and must always be nested under the config: key — never placed as top-level model properties. Placing them at the top level may appear to work in dbt Core but causes parse errors in dbt's Fusion engine.
# ✅ CORRECT — all governance configs under `config:`
models:
- name: fct_orders
config:
group: finance
access: public
contract:
enforced: true
columns:
- name: order_id
data_type: int
# ❌ WRONG — governance configs as top-level properties (breaks Fusion)
models:
- name: fct_orders
access: public # WRONG — not under config:
group: finance # WRONG — not under config:
contract: # WRONG — not under config:
enforced: true
columns:
- name: order_id
data_type: intThis applies to property YAML files only. In dbt_project.yml, use the + prefix for directory-level assignment (e.g. +group: finance, +access: private). In SQL files, use {{ config(access='public', group='finance') }}.
Adoption order
1. Groups & Access → 2. Contracts → 3. Versions → 4. Cross-Project Refs
(organize teams) (lock shapes) (manage changes) (split projects)- Groups & Access — no schema changes needed, start here
- Contracts — require declaring every column and data type in YAML
- Versions — needed when a model must introduce a breaking change that consumers need time to migrate to (an enforced contract is recommended alongside, but not required)
- Cross-Project Refs — require dbt Cloud Enterprise or Enterprise+ and a successful upstream production job. Do not set up cross-project refs if you cannot confirm the plan level is Enterprise or higher.
Contracts vs. Tests
| Contracts | Data Tests | |
|---|---|---|
| When | Build-time (pre-flight) | Post-build (post-flight) |
More from dbt-labs
Use this skill in a project
Open any RiverX project, search the Skills panel for dbt-labs/dbt-agent-skills/working-with-dbt-mesh, and install it in one click.
