name: airflow-workflow description: Execution guide for Airflow scheduled jobs — troubleshooting, updating, conn_id conventions, and cron references tags: - scheduler - airflow - workflow version: 1.0.0 user_invocable: false allowed_agents: - scheduler
Airflow Workflow
Execution guide for the scheduler subagent working with Airflow.
Troubleshoot a Failed Job
- Check job status —
get_scheduler_job(job_id) - List recent runs —
list_job_runs(job_id, limit=5)to find the failed run - Get error log —
get_run_log(job_id, run_id)for the failed run_id - Analyze the error — common failure categories:
- SQL syntax error → fix SQL and
update_job() - Connection failure → check conn_id in Airflow Connections (Admin > Connections), verify host is reachable from the scheduler worker
- Timeout → optimize the query or increase resources
- Permission denied → verify DB credentials in Airflow Connections (Admin > Connections)
- SQL syntax error → fix SQL and
- Fix and re-run:
- Update SQL:
update_job(job_id, sql_file_path=..., job_name=..., conn_id=...) - Manual trigger to verify:
trigger_scheduler_job(job_id) - Confirm success:
list_job_runs(job_id, limit=1)
- Update SQL:
Update an Existing Job
- Check current state —
get_scheduler_job(job_id)to see existing config - Pause the job —
pause_job(job_id)to prevent runs during update - Write SQL — use
write_fileoredit_fileto save the new SQL underjobs/<job_name>.sql - Update —
update_job(job_id, sql_file_path=..., job_name=..., conn_id=...) - Resume —
resume_job(job_id)to re-enable scheduling - Do not manually trigger after a normal create/update unless the user explicitly asks for an immediate run. Deterministic validation triggers and polls deliverable scheduler jobs after the agent returns the target.
Delete an Existing Job
- Confirm with the user — deletion is destructive.
- Delete — call
delete_job(job_id). - Honor the tool result — if
delete_jobreturnssuccess=0, report the deletion as failed or incomplete. Do not claim completion or success. - Verify only with direct lookup — use
get_scheduler_job(job_id)if you need a follow-up check. For Airflow, scheduling deletion is complete when the job is not found or is inactive/deleted. - Do not rely on list output —
list_scheduler_jobsmay omit an Airflow DAG after its file is removed even while Airflow metadata still exists and blocks re-creation with the same job id. - Use precise wording for partial cleanup — if metadata still exists but
the DAG is inactive/deleted, say scheduling has been removed and metadata
cleanup is pending. The same
dag_idmay not be immediately reusable via submit; use update or retry cleanup if needed. - Use explicit file deletion only —
delete_jobowns Airflow DAG file removal. For other files, use a dedicated delete-file tool if one is available; otherwise report that file deletion is unavailable. Do not overwrite or empty files as a substitute for deletion.
DB Connection (conn_id)
submit_sql_job and update_job require conn_id — the Airflow Connection ID for the target database.
The connection is managed entirely by Airflow (Admin > Connections) and resolved at runtime by the scheduler worker.
Available conn_id values are shown in the submit_sql_job and update_job tool descriptions (from scheduler.connections in agent.yml).
Naming Conventions
job_name:<frequency>_<domain>_<description>, e.g.daily_sales_summary,hourly_order_count- SQL file:
jobs/<job_name>.sql
Before calling submit_sql_job or update_job, create or update that SQL
file with write_file / edit_file. Do not ask the user to create the file
when filesystem tools are available.
Common Cron Expressions
| Schedule | Cron |
|---|---|
| Every day at 8am | 0 8 * * * |
| Every hour | 0 * * * * |
| Every 2 hours | 0 */2 * * * |
| Monday at 9am | 0 9 * * 1 |
| 1st of month at midnight | 0 0 1 * * |
Quick Reference
| Goal | Tool |
|---|---|
| Create SQL file | write_file(path="jobs/<job_name>.sql", content=...) |
| Submit SQL job | submit_sql_job(job_name, sql_file_path, conn_id) |
| Submit SparkSQL job | submit_sparksql_job(job_name, sql_file_path) |
| Check job status | get_scheduler_job(job_id) |
| List all jobs | list_scheduler_jobs(limit=20) |
| Trigger manual run | trigger_scheduler_job(job_id) only when explicitly requested or troubleshooting |
| View run history | list_job_runs(job_id) |
| View run log | get_run_log(job_id, run_id) |
| Pause / Resume | pause_job(job_id) / resume_job(job_id) |
| Update job | update_job(job_id, sql_file_path, job_name, conn_id) |
| Delete job | delete_job(job_id) |