How to use Otto to automatically investigate Dag failures and PR a fix

Labs
This feature is in Labs.

Otto is Astronomer’s AI agent, specialized in data engineering. Otto helps you write, test, upgrade, and investigate your Airflow Dags running on Astro, and you can interact with Otto from the Astro UI, Astro CLI, and the Astro API.

Architecture diagram showing a Dag failure triggering an Astro alert, which starts a second Dag that calls Otto to diagnose the failure and open a GitHub pull request with a fix.

This diagram shows the architecture you’ll implement in this tutorial.

  • Setting up an Astro alert that gets triggered on the failure of a Dag and responds by starting a run of the auto fix Dag.
  • The auto-fix Dag which uses Otto to investigate the failure having all necessary context about your environment, uses @task.agent to create a fix based on Otto’s suggestions, and submits a PR to GitHub for your review.

Assumed knowledge

To get the most out of this tutorial, you should have an understanding of:

Prerequisites

  • An API key of an LLM provider that is compatible with Pydantic AI. This tutorial uses an OpenAI API key. This API key is needed for the agentic tasks that create the GitHub PR. Otto interacts with models through Astronomer’s LLM gateway to run the root-cause-analysis, and does not need an API key.

Step 0: Sign up for Astro and install the Astro CLI

If you already have an Astro account and the latest version of the Astro CLI installed, continue with Step 1.

  1. If you don’t have an Astro account yet, sign up for a free trial of Astro, which gives access to Otto.

You do not need to select a template in the onboarding flow. Click Or skip this and go to your workspace when asked to select a template.

Astro onboarding flow with the option to skip choosing a template and go to your workspace.

  1. Use the following command to install the latest version of the Astro CLI.
1curl -sSL install.astronomer.io | sudo bash -s

If you cannot install the Astro CLI locally, you can still complete this tutorial by deploying the tutorial repository directly from GitHub using the GitHub integration.

Step 1: Create a new Astro Deployment

Create a new Deployment. You can choose any settings. Astronomer recommends the Development template for testing.

Create a new Deployment in the Astro UI.

Step 2: Fork and clone the tutorial repository

Fork and clone this GitHub repository.

It contains a fully functional Airflow project with two Dags:

  • create_tracking_labels: This is a test Dag designed to fail with an error for Otto to investigate automatically.
  • otto_rca_to_gh_pr: This is the Dag that runs the investigation.

Graph view of the otto_rca_to_gh_pr Dag in the Airflow UI.

The otto_rca_to_gh_pr Dag consists of six tasks:

  • parse_alert: Extracts the source Dag ID and run ID from the triggering alert. If the alert message doesn’t include a recognizable Dag ID or is missing a run ID, the task raises an error.
  • dedup_check: Checks GitHub for an existing open pull request labeled with the source Dag ID. If one already exists, the task skips the rest of the Dag run to avoid opening a duplicate fix. This is a simple example of deduplication logic. You might need more complex logic in a production setup specifying the issue to be fixed by task ID and deployment ID in addition to the Dag ID.
  • get_diagnosis: Requests a root cause diagnosis for the failed Dag run from Otto, using the Astro Organization ID, Deployment ID, and an investigation token.
  • fetch_source_file: Retrieves the current content of the failing Dag’s source file from the base branch of the GitHub repository.
  • propose_fix: An agent task that sends the diagnosis and current file content to an LLM, which proposes the smallest set of exact search-and-replace edits that resolve the diagnosed root cause.
  • open_pr: Applies the proposed edits to the source file, formats the result with ruff, then creates a branch, commits the change, and opens a labeled GitHub pull request.

You can review the full Dag code. The code is modularized, and imports helper functions from the include folder. The request_diagnosis function in include/airflow_rca shows the interaction with Otto.

The failing Dag and the auto-fix Dag are running in the same Astro Deployment for convenience in the context of the tutorial. You can use the otto_rca_to_gh_pr Dag to investigate any Dag failures in any of your Astro Deployments.

Step 3: Deploy the tutorial project

Run the following commands in your repository’s root to sign in to Astro and push code to your Astro Deployment, created in Step 1.

$astro login
$astro deploy

If you cannot install the Astro CLI locally, you can still complete this tutorial by deploying the tutorial repository directly from GitHub using the GitHub integration.

You can also interact with Otto from the Astro CLI. Just run astro otto and ask anything about Airflow, Astro, and your projects.

Step 4: Create a Deployment token

In order for an Astro alert to start a Dag in one of your Deployments, you need to give it a Deployment token.

  1. On your Deployment, click Access, then API Tokens, and Add API Token.

Access tab of an Astro Deployment showing the API Tokens sub-tab and the Add API Token menu with options to create a new Deployment API token.

  1. Create a new token with the name AlertToken of the Standard Kind with the Deployment Admin Role.

  2. Click Create API Token and store the token value in a safe location.

Step 5: Create an Astro alert

In order for any Dag failure to start the investigation Dag, you need to create an Astro alert with a Dag trigger.

  1. In the Astro UI, open the Alerting dropdown and click Alerts -> + New Alert.

Alerts page in the Astro UI showing the navigation to Alerting > Alerts and the New Alert button.

  1. The first part of the alert form describes when the alert should fire. Select the DAG Failure type, your workspace, and Deployment name. For this tutorial we’ll scope the alert to only trigger when the create_tracking_labels Dag fails.

Astro alert form set to the DAG Failure type with Critical severity, scoped to the Sandbox workspace, Otto RCA tutorial Deployment, and the create_tracking_labels Dag ID.

Note that if you are running the otto_rca_to_gh_pr Dag in the same Deployment as Dags that need to be fixed, be careful about selecting All DAGs for the alert. You want to avoid a situation where any failure in the otto_rca_to_gh_pr triggers another run of the same, creating an infinite loop.

  1. Next you need to add the DAG trigger notification channel. Click + New Notification Channel and create a channel with the name otto_rca_to_gh_pr Dag, the type DAG trigger, and aim it at your Deployment and the otto_rca_to_gh_pr Dag. Copy your Deployment API token that you saved at the end of Step 4 into the DEPLOYMENT API TOKEN field. Lastly make the channel available to your entire organization, workspace, or just to this tutorial Deployment.

New Notification Channel dialog with the DAG Trigger channel type selected, pointed at the Otto RCA tutorial Deployment and the otto_rca_to_gh_pr Dag, with a Deployment API token field and channel availability set to the entire organization.

  1. Click Create Notification Channel to create the channel and Create Alerts to save the alert.

Step 6: Create a GitHub token

In order to be able to raise a PR on GitHub, the AI agent needs access to your GitHub repository. For a production use case, you’ll likely want to setup a scoped GitHub App. For this tutorial, you can use a scoped personal access token.

  1. Go to your GitHub account’s Developer Settings and click Generate new token to create a new fine-grained token.

GitHub Developer Settings showing the Personal access tokens > Fine-grained tokens page and the Generate new token button.

  1. Give your GitHub any name and scope it to your fork of the tutorial repository.

  2. Add four permissions: Contents (Read and write), Metadata (Read-only), Pull requests (Read and write), and Issues (Read and write).

New fine-grained personal access token scoped to the forked tutorial repository, with Contents (Read and write), Issues (Read-only), Metadata (Read-only), and Pull requests (Read and write) permissions.

  1. Create the token and copy it to a safe location.

Step 7: Add environment variables and a connection

The last set up step is to add the necessary environment variables and the Airflow connection to your model provider to your Deployment.

  1. Go to your Astro Deployment and click Environment, then Environment Variables and Edit Deployment Variables.

Environment tab of an Astro Deployment showing the Environment Variables sub-tab and the Edit Deployment Variables button.

  1. Add the following three environment variables, marking all tokens and keys as SECRET with the toggle.

    • ASTRO_API_TOKEN: You can reuse the same Astro Deployment token you created in step Step 4. This is the credential the Airflow task uses to authenticate to Astro in order to be able to run the Otto investigation.
    • GITHUB_REPO: Your fork of the tutorial repository in the format <account>/<repo>.
    • GITHUB_TOKEN: Your GitHub token, retrieved in Step 6.
  2. Click Update Environment Variables to save your changes.

  3. Still on your Deployment’s environment tab, click Connections to add your Pydantic AI connection for the @task.agent task that drafts your PR.

Environment tab of an Astro Deployment showing the Connections sub-tab and the New Connection button.

  1. Select the Generic connection form and create a connection to your LLM provider. If you are using OpenAI, add the following values.

    • Connection ID: pydanticai_default
    • Connection Type: pydanticai
    • Password: Your OpenAI API Key.
    • Extra: {"model":"openai:gpt-5"}. You can use any valid model for your model provider.

Alternatively, you can use another LLM provider, as long as it is compatible with Pydantic AI and you adjust the extra provided to the pydantic-ai-slim[<your LLM provider>] in the requirements.txt file for your Astro project. For more options on how to configure the Pydantic AI connection used with the Common AI provider’s @task.agent decorator, see the Common AI provider connection documentation.

Step 8: Test the Dag

Now it is time to test this setup!

  1. Go to the Airflow UI and make sure both Dags are unpaused.

Airflow UI Dags list showing the create_tracking_labels and otto_rca_to_gh_pr Dags with their unpause toggles highlighted.

  1. Run the create_tracking_labels Dag manually. It should fail its last task with a KeyError.

  2. The failing Dag causes the Astro alert to run, and automatically triggers the otto_rca_to_gh_pr, which investigates the failure and proposes a fix.

  3. Wait for the Dag to finish, then check your GitHub repository for a new PR.

Automated GitHub pull request opened by the otto_rca_to_gh_pr Dag, showing Otto's diagnosis of a KeyError in print_tracking_labels caused by a list-mutation-during-iteration bug in drop_cancelled.

Conclusion

Congratulations! You’ve implemented a self-healing Dag using Otto to investigate a failure and AI orchestration with the Common AI provider to create a PR fixing the issue. This is just one of many possible ways you can include Otto in your pipelines. Another example is to post Otto’s diagnosis to Slack.