Catch failed Databricks job runs with the task and error behind each

Every morning: Databricks job runs that failed or timed out since yesterday, with the failing task, the error line and a link, and an ask about repairing.

Runs
Every day at 7:30
Posts
Asks you

What lands on your board

Acme LakehouseDatabricks failed jobs · Claude Code

2 Databricks jobs still failing

nightly_events_etl failed on a missing column, so a repair will fail again until the schema is fixed. Repair ml_feature_refresh now?

3 job runs failed since yesterday. nightly_events_etl and ml_feature_refresh are still broken; export_to_s3 succeeded on its next run.

JobTaskResultError
nightly_events_etlsilver_eventsFAILEDAnalysisException: [UNRESOLVED_COLUMN] user_agent cannot be resolved
ml_feature_refreshbuild_featuresTIMEDOUTRun exceeded the 2 h timeout
export_to_s3write_parquetRecoveredS3 throttling, succeeded at 05:10
Resolve
An example with made-up numbers. Your agent posts your real ones.

What it does

A nightly Databricks job that fails sends an email to its owner, if someone set notifications, and the dashboards that read its tables quietly show yesterday's numbers. With multi-task jobs, the run page says "Failed" while the cause sits in one task out of twelve.

The agent lists runs that ended badly since yesterday morning, finds the task that failed first (the others are usually marked as upstream failures), reads its error, and checks whether a later run already succeeded. For jobs still broken it asks whether to repair the run, which reruns only the failed tasks.

How it works

  1. 1List completed runs since yesterday

    GET <workspace>/api/2.2/jobs/runs/list?completed_only=true&start_time_from=<ms, 24 hours ago>&expand_tasks=true&limit=25, following next_page_token. Or databricks jobs list-runs --completed-only --start-time-from <ms> --expand-tasks -o json. Keep runs whose state.result_state is FAILED or TIMEDOUT.

  2. 2

    2Find the task that failed first

    Among the run's tasks, take the ones with state.result_state FAILED or TIMEDOUT; tasks marked UPSTREAM_FAILED only failed because of them. Note task_key, the cluster and how long it ran.

  3. 3Read the error

    GET <workspace>/api/2.2/jobs/runs/get-output?run_id=<task run_id> returns error and error_trace; keep the error and the last meaningful line of the trace (the exception class and message).

  4. 4Check for a later success

    GET /api/2.2/jobs/runs/list?job_id=<id>&limit=1 gives the newest run of the job. If it succeeded, mark the failure as recovered.

  5. 5

    5Ask before repairing

    Post the still-failing jobs and ask what to do. Only after a yes, call POST /api/2.2/jobs/runs/repair with the run_id and rerun_all_failed_tasks: true. A schema or code error needs a fix first; say so.

  6. Post it to the board

    With BRIEFKIN_TOKEN set, the agent sends the result as one card that updates in place every run. Without it, you get the report in the chat.

What you get

  • Still failing: job, failing task, error line, when it failed, link to the run (run_page_url).
  • Recovered: jobs that failed and later succeeded.
  • Timeouts listed separately, since they need a different fix.
  • The question: repair, look first, or leave.

Install and run it

Pick your agent, where the data comes from and how to schedule it; the commands below follow.

Agent
Data
Schedule
  1. Install the skill

    One command. It puts the SKILL.md in ~/.claude/skills and in ~/.agents/skills, which Codex, Cursor, Gemini CLI, Copilot CLI and OpenCode read too.

    shellcurl -fsSL https://briefkin.dev/skills/databricks-failed-jobs/install | sh
  2. Run it

    Ask Claude Code:

    promptRun the databricks-failed-jobs skill

    Or paste the prompt instead of installing:

    promptUsing the Databricks Jobs API 2.2 (or the Databricks CLI), list job runs that completed in the last 24 hours with expand_tasks=true, and keep those whose result_state is FAILED or TIMEDOUT. For each, find the task that failed first (ignore UPSTREAM_FAILED tasks), read its error with runs/get-output on the task run ID, and give the job name, task key, the error message and the last useful line of the trace, and run_page_url. Check the newest run of each job and say whether it has recovered. List still-failing jobs first and timeouts separately. Then ask me whether to repair any run; only call runs/repair with rerun_all_failed_tasks after I say yes.
  3. Put it on a schedule

    Every day at 7:30, from cron on any machine where Claude Code is signed in:

    crontab30 7 * * * claude -p "Run the databricks-failed-jobs skill"

    Add it with crontab -e. A laptop asleep at that time runs it when it wakes if you use launchd or Task Scheduler instead; GitHub Actions works for the API route.

  4. Send it to your board

    Connect Briefkin once with curl -fsSL https://briefkin.dev/install | sh and every run lands on your board as a question for you. How setup works

View the SKILL.mdRaw file
SKILL.md---
name: databricks-failed-jobs
description: "Every morning: Databricks job runs that failed or timed out since yesterday, with the failing task, the error line and a link, and an ask about repairing. Use when the user asks for this, or when it runs on a schedule."
---

# Databricks failed jobs

Every morning: Databricks job runs that failed or timed out since yesterday, with the failing task, the error line and a link, and an ask about repairing.

A nightly Databricks job that fails sends an email to its owner, if someone set notifications, and the dashboards that read its tables quietly show yesterday's numbers. With multi-task jobs, the run page says "Failed" while the cause sits in one task out of twelve.

The agent lists runs that ended badly since yesterday morning, finds the task that failed first (the others are usually marked as upstream failures), reads its error, and checks whether a later run already succeeded. For jobs still broken it asks whether to repair the run, which reruns only the failed tasks.

## Two ways to get the data

Use the API or MCP route when you have an MCP server, a CLI or an API token for the app. Otherwise, if you can drive a browser the user is signed in to (Claude in Chrome, a Playwright or Chrome DevTools MCP server), use the browser route. Say which one you used.

## Route A: API or MCP server

### What you need

- A Databricks personal access token or service principal token in `DATABRICKS_TOKEN` with `DATABRICKS_HOST`, with Can View on the jobs (Can Manage Run if you want repairs).
- Or the Databricks CLI configured with a profile for that workspace.

If something is missing, say what and stop; do not invent numbers.

### Steps

1. **List completed runs since yesterday** (Databricks): `GET <workspace>/api/2.2/jobs/runs/list?completed_only=true&start_time_from=<ms, 24 hours ago>&expand_tasks=true&limit=25`, following `next_page_token`. Or `databricks jobs list-runs --completed-only --start-time-from <ms> --expand-tasks -o json`. Keep runs whose `state.result_state` is `FAILED` or `TIMEDOUT`.
2. **Find the task that failed first**: Among the run's `tasks`, take the ones with `state.result_state` `FAILED` or `TIMEDOUT`; tasks marked `UPSTREAM_FAILED` only failed because of them. Note `task_key`, the cluster and how long it ran.
3. **Read the error** (Databricks): `GET <workspace>/api/2.2/jobs/runs/get-output?run_id=<task run_id>` returns `error` and `error_trace`; keep the error and the last meaningful line of the trace (the exception class and message).
4. **Check for a later success** (Databricks): `GET /api/2.2/jobs/runs/list?job_id=<id>&limit=1` gives the newest run of the job. If it succeeded, mark the failure as recovered.
5. **Ask before repairing**: Post the still-failing jobs and ask what to do. Only after a yes, call `POST /api/2.2/jobs/runs/repair` with the `run_id` and `rerun_all_failed_tasks: true`. A schema or code error needs a fix first; say so.

## Route B: the browser

### What you need

- Signed in to the Databricks workspace with Can View on the jobs (Can Manage Run if you want to repair); a workspace admin sees every job.

If something is missing, say what and stop; do not invent numbers.

### Steps

Start at https://accounts.cloud.databricks.com/. The user is signed in already; never type passwords or codes, and ask if a sign-in page appears.

1. **Open the workspace's job runs**: The account console lists your workspaces (on Azure it is `accounts.azuredatabricks.net`, or open the workspace URL directly). In the workspace, click **Jobs & Pipelines** in the left sidebar and open the **Job runs** tab, which shows runs across every job you can view.
2. **Filter to failures since yesterday**: Set the **Status** filter to `Failed` and `Timed out` (they are separate filters; do both) and the **Start time** filter to the last 24 hours. Each row shows the job, start time, duration and the run status; note the run count per job.
3. **Find the first failing task**: Click a run to open it. In the task graph, tasks marked **Upstream failed** only failed because an earlier one did; click the task shown as **Failed** or **Timed out**, read the error at the top of its output and the last meaningful line of the stack trace. Copy the run page URL for the report.
4. **Check for a later success**: Open the job (click its name) and look at the **Runs** tab: if a newer run shows **Succeeded**, the failure recovered and only needs a line.
5. **Ask before repairing**: List the jobs still failing and ask what to do. Only after a yes, open the failed run and click **Repair run**, which reruns the failed and skipped tasks; a schema or code error needs a fix first, so say so instead of repairing.

Note: The Job runs tab shows the runs the signed-in user can view; a personal account misses jobs owned by others unless it is an admin. The tab loads runs in pages while scrolling and keeps 60 days of history. Older workspaces still label the sidebar entry Workflows; it is the same page.

## The report

- **Still failing**: job, failing task, error line, when it failed, link to the run (`run_page_url`).
- **Recovered**: jobs that failed and later succeeded.
- **Timeouts** listed separately, since they need a different fix.
- The question: repair, look first, or leave.

## Post it to Briefkin

When `BRIEFKIN_TOKEN` is set, or `~/.config/briefkin/env` exists (the installer from https://briefkin.dev/docs writes it), also send the result to the user's Briefkin board as one card. Keep the `item_key` the same on every run so the card updates in place, use a new `event_id` per run, and put today's real numbers in place of the example ones. If the request fails, say so once and carry on.

```bash
[ -n "${BRIEFKIN_TOKEN:-}" ] || . ~/.config/briefkin/env
curl -sS -X POST "${BRIEFKIN_URL:-https://briefkin.dev}/v1/events" \
  -H "authorization: Bearer $BRIEFKIN_TOKEN" \
  -H "content-type: application/json" \
  -d @- <<'JSON'
{
  "v": 1,
  "event_id": "databricks-failed-jobs/<date of this run, e.g. 2026-10-16>",
  "item_key": "databricks-failed-jobs",
  "project": "Acme Lakehouse",
  "source": "Databricks failed jobs skill",
  "kind": "action",
  "title": "2 Databricks jobs still failing",
  "summary": "**3** job runs failed since yesterday. **nightly_events_etl** and **ml_feature_refresh** are still broken; **export_to_s3** succeeded on its next run.",
  "action": {
    "request": "nightly_events_etl failed on a missing column, so a repair will fail again until the schema is fixed. Repair ml_feature_refresh now?",
    "options": [
      "Repair ml_feature_refresh",
      "Show the full errors",
      "I will fix the schema first",
      "Leave both"
    ]
  },
  "widget": {
    "type": "Table",
    "props": {
      "columns": [
        "Job",
        "Task",
        "Result",
        "Error"
      ],
      "rows": [
        [
          "nightly_events_etl",
          "silver_events",
          "FAILED",
          "AnalysisException: [UNRESOLVED_COLUMN] user_agent cannot be resolved"
        ],
        [
          "ml_feature_refresh",
          "build_features",
          "TIMEDOUT",
          "Run exceeded the 2 h timeout"
        ],
        [
          "export_to_s3",
          "write_parquet",
          "Recovered",
          "S3 throttling, succeeded at 05:10"
        ]
      ]
    }
  }
}
JSON
```

Widgets come from the Briefkin catalog (https://briefkin.dev/v1/catalog). Without a token, just give the user the report.

## Run it on a schedule

Suggested: Every day at 7:30 (`30 7 * * *`). From cron, with the agent signed in on that machine:

```bash
30 7 * * * claude -p "Run the databricks-failed-jobs skill"
# Codex: codex exec, Gemini CLI: gemini -p, Copilot CLI: copilot -p, OpenCode: opencode run
```

Or use the agent's own scheduler (Claude Code routines, Codex automations, Claude or ChatGPT scheduled tasks): https://briefkin.dev/skills/databricks-failed-jobs#schedule

Source: https://briefkin.dev/skills/databricks-failed-jobs

What your agent needs

  • A Databricks personal access token or service principal token in DATABRICKS_TOKEN with DATABRICKS_HOST, with Can View on the jobs (Can Manage Run if you want repairs).

  • Or the Databricks CLI configured with a profile for that workspace.

Connecting Databricks

  1. Databricks managed MCP servers. Databricks hosts MCP servers inside your workspace. Through Unity Gateway they live at https://<workspace-hostname>/ai-gateway/mcp-services/<mcp-name>, and system.ai.dbsql runs SQL on a warehouse with your own Unity Catalog permissions (in beta as of October 2026). None of them covers the Jobs API, but the SQL server can read the system.lakeflow tables. Databricks' coding-agent guides cover connecting Claude Code, Codex and Cursor with OAuth (docs).
  2. Databricks CLI. After databricks auth login --host https://<workspace-hostname>, databricks jobs list-runs --completed-only --output json lists recent runs and databricks jobs get-run-output <run-id> shows a failed task's error.
  3. REST API with a token. The skill reads DATABRICKS_HOST and either DATABRICKS_TOKEN (a personal access token) or DATABRICKS_CLIENT_ID and DATABRICKS_CLIENT_SECRET for an OAuth service principal, which suits scheduled runs.

Run reports as a service principal with CAN VIEW on the jobs, CAN USE on one SQL warehouse and SELECT on the system tables it reads; it can then see every run but can't start, edit or delete a job.

Questions

What is the difference between repair and rerun?

A repair reruns only the failed and skipped tasks of the same run, keeping the successful tasks' output, so a 12-task job does not start over. A new run starts every task again. The skill only offers repairs, and only when you say so.

Does it see jobs owned by other people?

It sees the jobs the token can view. A personal token sees what you can see; for a team-wide report, use a service principal that has Can View on every production job, which also keeps the report working when someone leaves.

Do I need Briefkin to use the Databricks failed jobs skill?

No. The skill runs with your own agent and gives you the report in the chat. With a Briefkin token set, each run also posts it to your board as a asks you, so you can glance at it instead of asking again.

Which agents can run it?

Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot CLI, OpenCode, Windsurf and Amp all read SKILL.md files. The install command puts it in ~/.claude/skills and ~/.agents/skills, where they look. ChatGPT, the Claude app and Grok take the prompt instead. Pick your agent under "Install and run it" and the commands change to match.

Can it work without an API or MCP server, from my browser?

Yes. Switch the data source to "Your browser" and the steps change to the Databricks pages themselves: the agent opens accounts.cloud.databricks.com in a browser you are signed in to and reads the numbers off the page. Claude Code, Codex, Cursor, Claude app and ChatGPT can drive a browser out of the box; Gemini CLI, Copilot CLI and OpenCode need a Playwright or Chrome DevTools MCP server first. It is slower than the API and needs you signed in, so it suits a report you run by hand or from a scheduler on your own computer.

Answer your agents from one board, or from Telegram

Skills are free to use with any agent. Briefkin is where their results land: one board for every report, number and question your agents send, with a ping when something needs you.

Free during the open beta. No card.