Skip to content

Conversation

@amoghrajesh
Copy link
Contributor

closes: #57792

Problem

When retries=0 was explicitly set in DAG default_args, the value was being ignored during serialization, causing tasks to fall back to the default_task_retries configuration value instead of the explicitly set 0.

Example

[core]
...
default_task_retries = 3
...
from datetime import datetime
from airflow.sdk import DAG
from airflow.providers.standard.operators.bash import BashOperator

default_args = {
    'owner': 'airflow',
    'depends_on_past': False,
    'start_date': datetime(2024, 1, 1),
    'email_on_failure': False,
    'email_on_retry': False,
    'retries': 0,
}

dag = DAG(
    'test_dag',
    default_args=default_args,
    description='Test DAG that echoes a message and fails',
    schedule=None,
    catchup=False,
    tags=['test'],
)

test_task = BashOperator(
    task_id='echo_and_fail',
    bash_command='echo "This is a test message" && exit 1',
    dag=dag,
)

Cause

The serialization logic excluded values that matched schema defaults (e.g., retries=0) from the serialized json even when they differed from client_defaults (e.g., retries=3 from config). During deser, when retries was missing from the serialized task data it would result it to back to client_defaults.tasks.retries (3), losing the explicitly set value (0).

Fix

Updated the ser/deser logic to only exclude values that match both the schema default AND client_defaults. If a value matches the schema default but differs from client_defaults, it is included because that means it was explicitly set.

Additionally, added a generic method get_operator_const_fields() to detect fields with "const": true in the schema (like _is_sensor and _is_mapped), which should always be excluded when False, regardless of client_defaults.

Testing

Before:

os.environ['AIRFLOW__CORE__DEFAULT_TASK_RETRIES'] = '3'

def return_deserialized_task_after_serializng(retries):
    from datetime import datetime
    from airflow.sdk import DAG
    from airflow.providers.standard.operators.bash import BashOperator
    from airflow.serialization.serialized_objects import SerializedDAG
    from airflow.sdk.bases.operator import OPERATOR_DEFAULTS
    dag_0 = DAG(f'test_{retries}', default_args={'retries': retries}, start_date=datetime(2024, 1, 1))
    task_0 = BashOperator(task_id=f't{retries}', bash_command='echo', dag=dag_0)
    serialized_0 = SerializedDAG.to_dict(dag_0)
    task_data_0 = serialized_0["dag"]["tasks"][0]["__var"]
    client_defaults = serialized_0.get("client_defaults", {}).get("tasks", {})
    deserialized_dag_0 = SerializedDAG.from_dict(serialized_0)
    deserialized_task_0 = deserialized_dag_0.get_task(f't{retries}')
    
    return deserialized_task_0
ds_task_0 = return_deserialized_task_after_serializng(0)
ds_task_0.retries
Out[8]: 3

ds_task_1 = return_deserialized_task_after_serializng(1)
ds_task_1.retries
Out[16]: 1

After:

ds_task_0 = return_deserialized_task_after_serializng(0)
ds_task_0.retries
Out[6]: 0
ds_task_1 = return_deserialized_task_after_serializng(1)
ds_task_1.retries
Out[7]: 1

Tested with DAG:

from datetime import datetime
from airflow.sdk import DAG
from airflow.providers.standard.operators.bash import BashOperator

default_args = {
    'owner': 'airflow',
    'depends_on_past': False,
    'start_date': datetime(2024, 1, 1),
    'email_on_failure': False,
    'email_on_retry': False,
    'retries': 0,
}

dag = DAG(
    'test_dag',
    default_args=default_args,
    description='Test DAG that echoes a message and fails',
    schedule=None,
    catchup=False,
    tags=['test'],
)

test_task = BashOperator(
    task_id='echo_and_fail',
    bash_command='echo "This is a test message" && exit 1',
    dag=dag,
)

Result with no retries:

image

^ Add meaningful description above
Read the Pull Request Guidelines for more information.
In case of fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
In case of a new dependency, check compliance with the ASF 3rd Party License Policy.
In case of backwards incompatible changes please leave a note in a newsfragment file, named {pr_number}.significant.rst or {issue_number}.significant.rst, in airflow-core/newsfragments.

@ashb ashb added the backport-to-v3-1-test Mark PR with this label to backport to v3-1-test branch label Nov 5, 2025
@ashb ashb added this to the Airflow 3.1.3 milestone Nov 5, 2025
@ashb
Copy link
Member

ashb commented Nov 5, 2025

The ser dag tests are failing, as we've removed some default falsy values. I think that's okay, but we need to examine those closely.

@amoghrajesh amoghrajesh self-assigned this Nov 5, 2025
@amoghrajesh
Copy link
Contributor Author

👁️ looking at the failures

@ashb ashb changed the title Acknowledge default_args when its set as schema defaults Respect default_args in DAG when its set to¬ a "falsy" value Nov 5, 2025
@ashb ashb changed the title Respect default_args in DAG when its set to¬ a "falsy" value Respect default_args in DAG when its set to a "falsy" value Nov 5, 2025
@amoghrajesh
Copy link
Contributor Author

@ashb this one wasn't as easy as I thought. The PR is updated now, can you take a look?

@amoghrajesh amoghrajesh requested a review from ashb November 5, 2025 18:54
@amoghrajesh amoghrajesh requested a review from uranusjr November 6, 2025 07:48
@Lee-W Lee-W added the all versions If set, the CI build will be forced to use all versions of Python/K8S/DBs label Nov 11, 2025
@Lee-W
Copy link
Member

Lee-W commented Nov 11, 2025

rebasing for triggering the test

@amoghrajesh
Copy link
Contributor Author

@Lee-W it worked haha!

Copy link
Member

@Lee-W Lee-W left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Then others are nits from my end.

Copy link
Member

@ashb ashb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth also checking out works

@amoghrajesh amoghrajesh requested a review from uranusjr November 12, 2025 10:11
Copy link
Contributor

@ephraimbuddy ephraimbuddy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. My only issue is on performance

@amoghrajesh amoghrajesh merged commit c03fc79 into apache:main Nov 17, 2025
85 checks passed
@amoghrajesh amoghrajesh deleted the retries-bug-dag branch November 17, 2025 13:42
github-actions bot pushed a commit that referenced this pull request Nov 17, 2025
…ue (#57853)

(cherry picked from commit c03fc79)

Co-authored-by: Amogh Desai <amoghrajesh1999@gmail.com>
@github-actions
Copy link

Backport successfully created: v3-1-test

Status Branch Result
v3-1-test PR Link

github-actions bot pushed a commit to aws-mwaa/upstream-to-airflow that referenced this pull request Nov 17, 2025
…ue (apache#57853)

(cherry picked from commit c03fc79)

Co-authored-by: Amogh Desai <amoghrajesh1999@gmail.com>
potiuk pushed a commit that referenced this pull request Nov 17, 2025
…ue (#57853) (#58396)

(cherry picked from commit c03fc79)

Co-authored-by: Amogh Desai <amoghrajesh1999@gmail.com>
ephraimbuddy pushed a commit that referenced this pull request Nov 18, 2025
…ue (#57853) (#58396)

(cherry picked from commit c03fc79)

Co-authored-by: Amogh Desai <amoghrajesh1999@gmail.com>
ephraimbuddy pushed a commit that referenced this pull request Nov 19, 2025
…ue (#57853) (#58396)

(cherry picked from commit c03fc79)

Co-authored-by: Amogh Desai <amoghrajesh1999@gmail.com>
ephraimbuddy pushed a commit that referenced this pull request Nov 19, 2025
…ue (#57853) (#58396)

(cherry picked from commit c03fc79)

Co-authored-by: Amogh Desai <amoghrajesh1999@gmail.com>
ephraimbuddy pushed a commit that referenced this pull request Nov 20, 2025
…ue (#57853) (#58396)

(cherry picked from commit c03fc79)

Co-authored-by: Amogh Desai <amoghrajesh1999@gmail.com>
aaron-wolmutt pushed a commit to aaron-wolmutt/airflow that referenced this pull request Nov 20, 2025
ephraimbuddy pushed a commit that referenced this pull request Dec 3, 2025
…ue (#57853) (#58396)

(cherry picked from commit c03fc79)

Co-authored-by: Amogh Desai <amoghrajesh1999@gmail.com>
Copilot AI pushed a commit to jason810496/airflow that referenced this pull request Dec 5, 2025
itayweb pushed a commit to itayweb/airflow that referenced this pull request Dec 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

all versions If set, the CI build will be forced to use all versions of Python/K8S/DBs area:serialization backport-to-v3-1-test Mark PR with this label to backport to v3-1-test branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

retries from default_args are not respected

5 participants