$npx -y skills add dbt-labs/dbt-agent-skills --skill working-with-dbt-meshUse 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 v
| 1 | # Working with dbt Mesh |
| 2 | |
| 3 | **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. |
| 4 | |
| 5 | ## When to Use |
| 6 | |
| 7 | - 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. |
| 8 | - Versioning a model (`versions:`, `latest_version`, `latest_version_pointer`, `deprecation_date`) — this applies in a **single project**, not just multi-project setups |
| 9 | - Working in a dbt project that references models from other dbt projects |
| 10 | - Resolving ambiguity when multiple upstream projects have similarly-named models (e.g. multiple `stg_` models) |
| 11 | - Adding model contracts, access modifiers, or groups |
| 12 | - Setting up cross-project references with `dependencies.yml` |
| 13 | - Splitting a monolithic dbt project into multiple mesh projects |
| 14 | |
| 15 | **Do NOT use for:** |
| 16 | |
| 17 | - General model building or debugging (use the `using-dbt-for-analytics-engineering` skill) |
| 18 | - Unit testing models (use the `adding-dbt-unit-test` skill) |
| 19 | - Semantic layer work (use the `building-dbt-semantic-layer` skill) |
| 20 | |
| 21 | ## First: Orient Yourself in a Multi-Project Setup |
| 22 | |
| 23 | Before writing or modifying any SQL in a project that uses dbt Mesh, follow these steps: |
| 24 | |
| 25 | ### 1. Read `dependencies.yml` |
| 26 | |
| 27 | This file at the project root tells you which upstream projects exist: |
| 28 | |
| 29 | ```yaml |
| 30 | # dependencies.yml |
| 31 | projects: |
| 32 | - name: core_platform |
| 33 | - name: marketing_platform |
| 34 | ``` |
| 35 | |
| 36 | If 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()`. |
| 37 | |
| 38 | ### 2. Understand how upstream data gets into this project |
| 39 | |
| 40 | In a mesh setup, upstream project models replace what would alternatively be sources: |
| 41 | |
| 42 | | Alternative | Mesh multi-project | |
| 43 | |---|---| |
| 44 | | `{{ source('stripe', 'payments') }}` | `{{ ref('core_platform', 'stg_payments') }}` | |
| 45 | | Data comes from raw database tables | Data comes from another dbt project's public models | |
| 46 | | Defined in `sources.yml` | Declared in `dependencies.yml` | |
| 47 | |
| 48 | The upstream project has already staged and transformed the raw data. Your project builds on top of their public models, not their raw sources. |
| 49 | |
| 50 | ### 3. Disambiguate similarly-named models |
| 51 | |
| 52 | 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()`: |
| 53 | |
| 54 | ```sql |
| 55 | -- Correct: explicit project name, no ambiguity |
| 56 | select * from {{ ref('core_platform', 'stg_customers') }} |
| 57 | select * from {{ ref('marketing_platform', 'stg_customers') }} |
| 58 | |
| 59 | -- WRONG: dbt cannot determine which project's stg_customers you mean |
| 60 | select * from {{ ref('stg_customers') }} |
| 61 | ``` |
| 62 | |
| 63 | ### 4. Check existing patterns in the codebase |
| 64 | |
| 65 | Before writing new SQL: |
| 66 | - Search for existing two-argument `ref()` calls to see which upstream projects and models are already in use |
| 67 | - Look at the upstream project's YAML for `access: public` models — only these are referenceable cross-project |
| 68 | - The first argument of `ref()` must exactly match the `name` field in the upstream project's `dbt_project.yml` (case-sensitive) |
| 69 | |
| 70 | ### 5. Know what you can and cannot reference |
| 71 | |
| 72 | | Upstream model access | Can you `ref()` it cross-project? | |
| 73 | |---|---| |
| 74 | | `access: public` | Yes | |
| 75 | | `access: protected` (default) | No — only within the same project | |
| 76 | | `access: private` | No — only within the same group | |
| 77 | |
| 78 | If you need a model that isn't `public`, coordinate with the upstream team to widen its access. |
| 79 | |
| 80 | ## Cross-Project Refs Require dbt Cloud Enterprise |
| 81 | |
| 82 | 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: |
| 83 | |
| 84 | 1. **If `dependencies.yml` already has a `projects:` key and the project is actively using cross-project refs** — Enterprise is already in place. Proceed. |
| 85 | 2. **Otherwise** — ask the user to confirm they are on dbt Cloud Enterprise or Enterprise+ before adding `projects:` to `de |