dbt-labs / dbt-labs/dbt-autofix
Autofix bare-string exposure `depends_on` entries into `ref()`
- Dominant language
- Python
- Stars
- 88
- Forks
- 19
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 13
Description
# Autofix bare-string exposure `depends_on` entries into `ref()`
## Summary
`dbt-autofix` should rewrite exposure `depends_on` entries that are written as
bare strings (a plain resource name) into proper `ref('...')` calls.
## Background
Per the [exposure properties docs](https://docs.getdbt.com/reference/exposure-properties),
every `depends_on` entry must be a `ref('...')`, `source('...', '...')`, or
`metric('...')` call. A bare string like `"my_model"` is not a valid form.
The two engines handle the invalid form differently:
- **dbt-core** parses the exposure but silently discards the bad entry. The
resulting exposure depends on nothing (`depends_on.nodes: []`), so the mistake
goes unnoticed and the exposure is effectively disconnected from the DAG.
- **The Rust engine (Fusion)** raises a hard error:
`Exposure depends_on entry '' does not call ref(), source(), or metric().`
Because core swallows it, these bare-string entries survive in real projects and
only surface as a parse error once a project moves to the newer engine.
## Example
Before:
```yaml
exposures:
- name: milestone_details
type: dashboard
url: https://example.com/dashboards/1321
depends_on:
- "flattened_table_milestones"
owner:
name: Product Analytics
email: analytics@example.com
```
After:
```yaml
exposures:
- name: milestone_details
type: dashboard
url: https://example.com/dashboards/1321
depends_on:
- ref('flattened_table_milestones')
owner:
name: Product Analytics
email: analytics@example.com
```
## Proposed behavior
- Only touch entries that are bare strings; leave entries already using
`ref()`/`source()`/`metric()` unchanged.
- Resolve the bare name against the project graph:
- matches a model or seed -> rewrite to `ref('')`
- no match, or ambiguous -> leave as-is and warn, since autofix cannot know
whether it should be a `source()`/`metric()` or a typo.
- Skip names set dynamically via variables, consistent with the concern in #241.
## Notes
Seen in multiple real-world projects. Low individual impact but a clean,
deterministic rewrite for the common model/seed case.
Contributor guide
Assessment
This issue has not been assessed yet.