agent loop: re-running the same dbt model after no-op changes
Stops agent loops that re-run the same dbt model after no-op changes. Use when an agent keeps invoking dbt run on unchanged models, when CI rebuilds everything every time, or when the agent cant tell what changed. Not for real model failures, for test failures, or for seed/snapshot loops.
TL;DR
The agent re-runs models because nothing tells it what changed: it shells out to dbt run with no selection instead of diffing. Fix it by making the agent use dbt ls --select state:modified+ (with a prior manifest as the state) or slim CI, so only changed models and their downstream get built.
agent loop: re-running the same dbt model after no-op changesUse this when
- An agent re-runs dbt models that didnt change
- Every agent iteration rebuilds the whole project
- CI runs full builds on docs-only PRs
Not for this skill when
- The model genuinely fails (thats the model)
- Tests fail (thats the data)
- Seeds or snapshots loop (different mechanism)
Steps
- Show the agent how to select only what changed using state comparison:
dbt ls --select state:modified+ --state ./target-prod --target prodExpected output: only models modified relative to the prod manifest, plus downstream. The agent should run this selection, not bare dbt run.
- Wire the agent's run command to that selection:
dbt run --select state:modified+ --state ./target-prodExpected output: unchanged models are skipped. Keep the prod manifest artifact where the agent can fetch it (CI artifact or object storage).
- For file-watching loops, debounce and diff before running:
# agent pseudo-flow: git diff --name-only, map to models, run selectionExpected output: a no-op edit (whitespace, comments) maps to zero models and the agent skips the run entirely instead of rebuilding.
- Add a guard the agent checks before any run:
Before dbt run: list changed files, map to models, if empty then skip and report no-op.Expected output: the loop terminates instead of spinning. Agents without this guard treat "run dbt" as an unconditional step.
Variant phrasings
agent rebuilds after its own formatting changes
dbt format rewrites files, which looks like a change. Exclude formatting-only diffs from the selection, or run format before the diff.
slim CI still builds too much
state:modified+ includes downstream; that is correct (downstream may be stale). If it is too much, the model graph needs better slicing, not a return to full builds.
Why it happens
Agents operate step by step with no memory of what changed unless you give them a diff mechanism. dbt run with no selection is the path of least resistance, and dbt happily rebuilds everything. State-based selection exists precisely for this, but agents dont discover it on their own; it has to be in their instructions.
Edge cases
- The state manifest must be fresh; a stale prod manifest makes everything look modified.
- Macro changes dont always register as model modifications; include macro paths in the diff mapping.
- Deleting a model file looks like "nothing changed" to naive diffs; handle deletions explicitly or the warehouse keeps the stale table.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_z6Nbty2oDHHJROcFMLFuOg
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.