Self-Healing Pipelines - Dagster
Automatically recover from failed Dagster runs by dispatching every op failure to a DinoAI background agent — the pipeline healer. The moment a step fails, a Dagster @failure_hook captures the exception and stack trace and hands it to the agent. The agent posts a triage summary, applies the minimal fix on a new branch, and opens a pull request — no manual intervention required.
Before You Start
Paradime
Your Paradime API endpoint, API key, and API secret — generate these under Workspace Settings → API. Make sure to enable
DinoAI agent APIcapabilities. Requires Admin access.API keys are workspace-scoped: generate the key from the workspace whose connected repository contains your
.dinoai/agents/folder — the agent always runs in the workspace that issued the key.
Recommended reading
Before proceeding, read the Programmable Agents section under Products → DinoAI: Quick Start, YAML Configuration, and Tools Reference.
Integrations
The following must already be connected in Paradime:
GitHub - the healer creates branches and opens PRs against the workspace repository
Slack - the healer posts its triage summary and progress to
#dagster-dinoai-self-healing
What You'll Build
One DinoAI agent YAML — the
dagster-pipeline-healer— that triages failures, posts a summary, and opens a single fix PR per failed runA Dagster
@failure_hookthat fires the healer automatically when any op fails, pre-populated with the run ID, job name, failed step, and full stack traceJobs with the hook attached at definition time — no UI toggle, every run is covered
What Happens During a Healing Run
The hook is fire-and-forget: it dispatches the failure and returns immediately, so the Dagster run's teardown is never blocked by the agent session. A typical healing run completes in 2–6 minutes from step failure to open PR.
The Fix PR
Each failed run produces exactly one PR, with every distinct error documented — the verbatim error string, the file changed, and the fix applied:
Create the Agent YAML
Create the healer agent in .dinoai/agents/. The file must exist on the branch your Paradime workspace tracks (usually main) before the first trigger — the agent is loaded from the remote repository, not your local checkout.
Merge the agent YAML to your default branch before triggering. DinoAI loads agent definitions from the default branch of the workspace repository — an agent YAML sitting on a feature branch, an open PR, or only in your local checkout is invisible to trigger_run, and the session will fail with no messages. Any later edits to the YAML also only take effect once they are merged.
Adapt the error → file mapping in step 3 of the goal to your own repository layout. The mapping is what lets the agent go from a stack trace to the right file without exploring the whole repo.
Add the Failure Hook
The hook fires in-process the moment an op fails — no sensor polling, no daemon dependency. Create dagster_project/hooks.py:
Then attach the hook to your jobs at definition time:
Finally, set the three environment variables wherever your Dagster code runs — dagster dev locally, or your deployment's environment configuration in production:
PARADIME_API_ENDPOINT
Your Paradime API endpoint
PARADIME_API_KEY
Your Paradime API key
PARADIME_API_SECRET
Your Paradime API secret
The hook is a graceful no-op when the env vars are unset: it logs a warning and returns. Local development without credentials never fails a run because of the hook, and the original op failure is always surfaced normally in Dagster either way.
Materializing assets directly from the asset graph runs Dagster's internal __ASSET_JOB, which carries no hooks. Always launch through a hooked job to get self-healing coverage.
Test It End-to-End
Verify the loop with a deliberate, controlled failure. Two rules make or break the test:
The break must be a runtime error, not a parse error. A typo'd
ref()breaks dbt parsing, which breaks Dagster's code-location load itself — the run dies with "Could not load job definition" before any op starts, and the hook never fires. Instead, reference a column that doesn't exist in the source table:
This parses fine, Dagster loads, and the model fails in the warehouse with Unrecognized name: grand_prix_sponsor — a real op failure that fires the hook.
The break must be pushed to the branch your Paradime workspace tracks. The agent clones the remote repository — a local-only break fires the hook, but the agent finds healthy code and has nothing to fix.
Push the break, then launch the hooked job from the Dagster UI. Watch the run in three places, in the order things happen:
Dagster event log — right after
STEP_FAILUREyou'll see the dispatch confirmation:Triggered DinoAI agent 'dagster-pipeline-healer' … Result: ok=True agent_session_id='…' status='queued'Slack —
#dagster-dinoai-self-healingreceives the triage summary, then progress updatesGitHub — the fix PR appears a few minutes later, citing the exact error string
Merge the PR to heal the pipeline and close the loop.
File Structure
If an agent session fails immediately with no messages, the API key likely belongs to the wrong workspace — trigger_run always runs the agent in the workspace that issued the key. Also note that a long-running dagster dev process keeps the environment variables it started with; restart it after rotating or switching keys.
Related Docs
Last updated
Was this helpful?