A curated collection of Agent Skills for working with Orchestra, for agents to effectively implement standards, common workflows, and manage pipelines.
89%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
The router. Identify which task broke and why, then route to the skill that fixes it.
This skill draws a clean line: it identifies and classifies; the fix-* skills fix. Do not
attempt code repairs, schema changes, or branch validation here — that is the fixer's job.
Narrate each step briefly, like a data engineer. Never print secrets/tokens.
MCP is preferred but optional. If the Orchestra MCP tools aren't present, use the public REST API
with $ORCHESTRA_API_KEY (check the env — it's often already set). If neither MCP nor a key is
available, point the user at the Orchestra MCP setup docs (https://docs.getorchestra.io/docs/mcp)
or ask for an API key, then stop.
whats_broken, diagnose, pipeline_context — each answers a whole
step below in one call. Prefer them (see §1a).list_pipeline_runs, list_task_runs, list_operations,
list_task_run_logs, download_task_run_log, list_task_run_artifacts,
list_pipelines — see ../../references/orchestra/mcp/tools-quick-ref.md.https://app.getorchestra.io/api/engine/public — header
Authorization: Bearer $ORCHESTRA_API_KEY.If a call comes back 403, the workspace does not have the Metadata API enabled. Say so and ask the user to have a workspace admin enable it — do not retry or fall back to guessing.
If whats_broken and diagnose are available, they collapse Steps 1-3 and you should
reach for them first. Steps 1-3 remain the fallback for a client without them, or for
anything they do not cover.
| You have | Call | You get |
|---|---|---|
| Nothing — "what's broken?" | whats_broken() | Every failing run in the last 24h, each with its failed tasks, messages and anomalies. Widen with window_hours, narrow with environment. |
| A pipeline run ID or URL | whats_broken(), then pick the run by ID | The same digest; the run you want is in it if it failed inside the window |
| A task run ID | diagnose(task_run_id) | Parameters, upstream statuses, log tail, artifact names |
| A pipeline name, alias or ID | pipeline_context(alias) | Definition, integrations, recent outcomes, duration baseline |
The usual sequence is whats_broken() → read the digest → diagnose(<failed task run id>)
on the first failed task. That is enough to classify and route in Step 4. Go deeper only
when it is not: the digest and the log tail say when they were truncated, and
download_task_run_log / list_operations take it from there.
Two things to carry across from the digest, since Step 4 needs them: the run's branch
(the feature-branch guard in Step 2 still applies) and the failed task's integration.
The user may give you several forms. Extract the IDs before doing anything else.
https://app.getorchestra.io/pipeline-runs/{pipeline_run_id}
https://app.getorchestra.io/pipeline-runs/{pipeline_run_id}/task-runs/{task_run_id}
https://app.getorchestra.io/pipelines/{pipeline_id}/runs/{pipeline_run_id}
https://app.getorchestra.io/pipelines/{pipeline_id}get_pipeline_run /
GET /pipeline_runs/<id>), then as a task run ID (get_task_run / GET /task_runs/<id>, whose
pipelineRunId gives you the run). Both find a run however old it is. If neither matches, treat
it as a pipeline ID and look up its recent runs.list_pipelines, then find its latest FAILED run.whats_broken(), or list_pipeline_runs with
status=FAILED as the fallback. If several pipelines failed, present a
one-line-per-pipeline triage table and ask which to take.get_pipeline_run(pipeline_run_id=<RID>) # MCP
GET /pipeline_runs/<RID> # RESTUnlike list_pipeline_runs, this needs no time_from/time_to: it finds the run however long ago
it ran.
Capture: id (RID), pipelineId (PID), pipelineName, runStatus, message, branch, commit,
envName, triggeredBy. The run's branch is where the Orchestra YAML lives (not necessarily
the code branch).
Feature-branch guard: if the failure is on a non-main branch from a MANUAL trigger while
scheduled/main runs are green, this is likely mid-development, not an incident. Confirm with the
user before going further (see ../../references/orchestra/pipeline/diagnosis-patterns.md →
FEATURE_BRANCH_RUN).
list_task_runs(pipeline_ids=<PID>, status=FAILED, time_from=<now-7d>, time_to=<now>) # also pull status=WARNING for context
GET /task_runs?pipeline_ids=<PID>&page_size=50&time_from=<now-7d>&time_to=<now> # REST: filter to this RID client-sideGotcha: pipeline_run_ids does not filter /task_runs over REST — filter by pipelineRunId
yourself. /task_runs returns only the last 24 hours unless you pass time_from/time_to (at
most 7 days apart), and includes superseded attempts unless you
pass include_superseded=false, so a retried task shows up twice.
Identify the first FAILED task (downstream FAILED/SKIPPED tasks are usually symptoms of it). Capture, for that task:
integration (e.g. PYTHON, DBT_CORE, SNOWFLAKE, HTTP, FIVETRAN, AIRBYTE_*)integrationJob, taskName, taskId, id (TRID)message, externalStatus, externalMessage, numberOfAttemptstaskParameters, runParameters, connectionIdPull just enough evidence to classify — the failed task's messages, and if the integration alone doesn't decide it, a quick look at logs/artifacts:
list_task_run_logs(<RID>, <TRID>) → download_task_run_log(... range_header="bytes=-262144")
list_task_run_artifacts(<RID>, <TRID>) # dbt: run_results.json is the tell for data-test failsDon't deep-dive here. Reading full logs, reproducing locally, and downloading every artifact is the fixer's job — gather only what you need to route correctly.
Classify using the failed task's integration + messages + minimal evidence, cross-referenced with
../../references/orchestra/pipeline/diagnosis-patterns.md. Then route:
| Cause you identified | Route to |
|---|---|
Python task — code / dependency / destination-schema issue (integration=PYTHON; traceback, ModuleNotFoundError, bad logic, script writes a shape the destination rejects) | invoke fix-pipeline-python-task |
dbt task — code / config issue (DBT_CORE; compilation error, bad ref/source, SQL identifier, missing column, profiles.yml/target error) | invoke fix-pipeline-dbt-task |
Orchestra-platform / configuration issue (pipeline YAML misconfig, wrong/missing task inputs, task ordering, env/connection wiring, a transient Orchestra-side blip needing a plain retry, or an Orchestra-backed pipeline needing update_pipeline) | invoke fix-orchestra-pipeline |
| Any other cause (see §5) | handle here |
State the routing decision in one line before handing off, e.g.:
Identified: the dbt task
transform_corefailed with a compilation error — an issue with the dbt task code. Handing off tofix-pipeline-dbt-task.
Pass the fixer everything it needs so it doesn't re-identify: RID, PID, failed TRID, integration,
taskParameters (verbatim), branch/commit, and your cause classification. If the fixer later
discovers the category was wrong (e.g. a "dbt code" failure is really a data-quality test failure),
it hands back here.
These aren't python-code, dbt-code, or Orchestra-config problems, so there's no fix-* skill to
call. Identify precisely, then report with the right next action — don't edit code or data, and
don't retry data-writing tasks without the user's OK.
run_results.json). Decide with the user: legitimate data issue
(notify the data owner, don't touch the data) vs. an overly strict threshold (they may adjust it).ERROR STALE) — an upstream source hasn't refreshed. Point at the ingestion
task/pipeline that feeds it; this is usually a data/upstream issue, not code.platformLink and connectionId/connector id and tell the user what to fix in that
product's UI. Do not open a Git PR. "Sync already running" → increase the schedule interval.401/403, expired/rotated creds, insufficient privileges) — name the connectionId to
update and give the exact GRANT/IAM change. User action.SNOWFLAKE query errors, HTTP non-2xx, AWS/Azure/GCP jobs) — diagnose
with diagnosis-patterns.md. If the failure is misconfiguration in version-controlled pipeline
YAML, that's an Orchestra-config issue → route to fix-orchestra-pipeline instead. If it's a SQL
bug in a repo, treat it as a code fix and open a PR per fix-orchestra-pipeline Step 5.Read ../../references/orchestra/pipeline/diagnosis-patterns.md for per-integration signals and
../../references/orchestra/pipeline/remediation-playbooks.md for the recommended action.
When routing, keep it to the handoff line (§4) plus the IDs you're passing on.
When handling a cause yourself (§5), present a compact diagnosis and a recommendation:
## Diagnosis: `<pipeline name>`
- **Failed task:** `<task name>` (`<INTEGRATION>` / `<integrationJob>`)
- **Cause:** <one specific sentence — which object/test/credential/endpoint, not just "error">
- **Category:** DATA / VENDOR / AUTH / NETWORK / TIMEOUT / UPSTREAM / …
- **Evidence:** <quoted log line or external message; which operation failed>
- **Confidence:** High / Medium / Low
**Recommended next step:** <one line — who does what, with the exact GRANT/IP/UI path if relevant>fix-* skills.taskParameters so it doesn't repeat identification.list_* calls..tessl-plugin
skills
orchestra
skills
account-health-check
references
build-data-reconciliation-pipeline
configure-dbt-build-after
configure-dbt-source-freshness
create-orchestra-pipeline
fix-orchestra-pipeline
fix-pipeline-dbt-task
fix-pipeline-python-task
identify-pipeline-error
merge-duplicate-pipelines
references
orchestra-dbt-slim-ci-setup
setup-incident-slack-summary
triage-orchestra-pipeline
write-bigquery-dq-tests
write-clickhouse-dq-tests
write-databricks-dq-tests
write-snowflake-dq-tests