Hourly Snowflake task failure tickets in Linear and Slack
Sweep Snowflake every hour for failed tasks, open a Linear ticket for each one, and post a Slack summary so nothing rots silently in the warehouse.
Build a code workflow that monitors Snowflake task failures every hour and files Linear tickets plus a Slack summary so nothing rots silently in the warehouse.
Trigger: cron, every hour at :05 (so SNOWFLAKE.ACCOUNT_USAGE.TASK_HISTORY has time to catch up on the previous hour's runs).
Step 1 — Query Snowflake for recent failures. Use the Snowflake Execute SQL Statement operation against SNOWFLAKE.ACCOUNT_USAGE.TASK_HISTORY. Select DATABASE_NAME, SCHEMA_NAME, NAME (task name), QUERY_ID, ERROR_CODE, ERROR_MESSAGE, SCHEDULED_TIME, COMPLETED_TIME, and RUN_ID where STATE = 'FAILED' and SCHEDULED_TIME >= DATEADD(hour, -1, CURRENT_TIMESTAMP()). Order by SCHEDULED_TIME desc. If the result set is empty, exit the workflow without posting anything.
Step 2 — Deduplicate against Linear. For each failed row, call Linear's Search Issues operation with the QUERY_ID as the search text. If a ticket containing that QUERY_ID already exists, skip the row so the same failure does not open a second ticket.
Step 3 — Open a Linear ticket per remaining failure. Call Linear's Create Issue in a configured team (expose the team ID as a workflow input). Title: "Snowflake task failed: <DATABASE_NAME>.<SCHEMA_NAME>.<TASK_NAME>". Description (markdown): include the error code, error message, query ID, run ID, scheduled time, completed time, and the fully-qualified task identifier. Append the QUERY_ID on its own line as `QUERY_ID: <id>` so Step 2 can match it on future runs. Capture the issue identifier and url returned from each create call.
Step 4 — Post one Slack summary. Use Slack's Send a Message operation to a configured channel (expose channel as a workflow input). Body should say something like "Snowflake task failures in the last hour: N" followed by a bulleted list where each bullet is `<DATABASE>.<SCHEMA>.<TASK_NAME> — <Linear issue identifier> <issue url>`. Send exactly one Slack message per run; do not post per-failure. If every failure was deduplicated in Step 2, still post a short note saying N failures recurred and link the existing Linear tickets so on-call sees them.
Inputs the workflow should expose: Snowflake warehouse to use for the query, Linear team ID, Slack channel ID, and an optional database/schema allowlist to scope the sweep. Use bind variables in the SQL where appropriate. Keep the flow deterministic; no agent reasoning is needed.
Additional information
What does this prompt do?
- Checks Snowflake every hour for tasks that failed in the last 60 minutes.
- Opens a Linear ticket for each failed task with the database, schema, task name, error code, error message, query ID, and scheduled time.
- Skips failures that already have a Linear ticket so the same broken task doesn't pile up duplicates.
- Posts one Slack message summarizing the count of failures with links to every Linear ticket that was opened.
What do I need to use this?
- A Snowflake account with permission to read TASK_HISTORY in ACCOUNT_USAGE.
- A Linear workspace and the team you want failure tickets filed in.
- A Slack workspace and the channel you want the hourly summary posted to.
How can I customize it?
- Change how often it runs or shift the window if hourly is too noisy or too quiet.
- Pick which Linear team, project, label, or priority the tickets land under.
- Pick which Slack channel gets the summary, and add an at-mention for an on-call group.
- Narrow the sweep to a specific database, schema, or warehouse if you only care about production tasks.
Frequently asked questions
Will this open the same ticket over and over for a task that keeps failing?
What if there were no failures in the last hour?
Do I need a paid Linear plan?
Can I send the alert somewhere other than Slack?
Why every hour at five past the hour instead of on the hour?
Stop letting Snowflake task failures rot in the warehouse.
Connect Snowflake, Linear, and Slack once, and Geni will sweep for failures every hour and turn each one into a tracked ticket.