Skip to content

ExternalTaskSensor External link with incorrect URL #61850

Open

Description

@ecodina

Apache Airflow version

3.1.7

If "Other Airflow 3 version" selected, which one?

No response

What happened?

The "External DAG" that appears in the details page of an ExternalTaskSensor instance contains a wrong URL.

It assumes that the task is waiting for a run with the exact same logical date even if you specify another logical date.

What you think should happen instead?

No response

How to reproduce

  1. Create a Dag with a Cron trigger of (example) 35 22 * * * that contains an EmptyOperator
  2. Create a Dag with a Cron trigger of (example) 40 22 * * * that contains an ExternalTaskSensor that waits for Dag 1 and uses a function for execution_date_fn similar to :
def get_last_execution_date_of_dag(logical_date: datetime.datetime, **kwargs):
    import airflow_client.client

    from airflow.configuration import conf
    from myprovider.hooks.api_token import AirflowAPITokenHook  # Won't work, you need to obtain the token somehow

    hook = AirflowAPITokenHook(airflow_api_token_conn_id="airflow_api_token_default")
    token = hook.get_token()

    base_url = conf.get("api", "base_url")

    dag_id = kwargs["task"].external_dag_id

    configuration = airflow_client.client.Configuration(
        host=base_url, access_token=token
    )
    with airflow_client.client.ApiClient(configuration) as api_client:
        api_instance = airflow_client.client.DagRunApi(api_client)

        api_response = api_instance.get_dag_runs(
            dag_id, logical_date_lte=logical_date, limit=1, order_by=["-logical_date"]
        )

        if not api_response.dag_runs or len(api_response.dag_runs) == 0:
            raise ValueError(
                f"No previous dag_run found for DAG {dag_id} before {logical_date}. Please ensure the parent Dag has at least one run before this date."
            )

        last_dag_run = api_response.dag_runs[0]
        parent_logical_date = last_dag_run.logical_date

        print(
            f"Found last dag_run for DAG {dag_id} before {logical_date}: {parent_logical_date}"
        )

    return parent_logical_date

When Dag 2 gets executed, you'll see this line in the log:

Found last dag_run for DAG dag1 before 2026-02-11 22:35:00+00:00: 2026-02-11 22:30:00+00:00

Which is correct.

However, the link that is generated is:

https://myairflow.example.com/dags/dag1/runs/scheduled__2026-02-11T22:35:00+00:00

Which contains the run ID of Dag2, not Dag1.

Operating System

Debian GNU/Linux 12 (bookworm)

Versions of Apache Airflow Providers

No response

Deployment

Docker-Compose

Deployment details

No response

Anything else?

No response

Are you willing to submit PR?

  • Yes I am willing to submit a PR!

Code of Conduct

Activity

  1. Mr-Neutr0n commented on Feb 13, 2026

    @Mr-Neutr0n
    Contributor

    I opened a fix for this in #61852. The root cause was that ExternalDagLink.get_link() was using the current DAG run's run_id to build the URL, which embeds the current DAG's logical date. When execution_delta or execution_date_fn points to a different logical date, the external DAG's run has a different run_id, so the link was broken.

    The fix resolves the external DAG's actual run_id by querying the database for the DagRun matching the target logical date (accounting for execution_delta). Falls back gracefully to the original behavior if the lookup doesn't find a match.

  2. sjyangkevin commented on Oct 10, 2026

    @sjyangkevin
    Contributor

    Hi, I would like to pick this up if no active work in ongoing. I've opened an PR to address the issue, and also for #66695

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:corekind:bugThis is a clearly a bugneeds-triagelabel for new issues that we didn't triage yet

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions