Airflow CTL Version
Latest stable version
Airflow CTL Command
airflowctl dags trigger example_simplest_dag --dag-run-id <run_id> --env production
Keyring Backend / Version
Keyring Backend/Headless
Auth Type
Token
What is the current behaviour?
airflowctl dags trigger fails against any Airflow deployment running a version earlier than 3.2.0, with:
{'type': 'extra_forbidden', 'loc': ['body', 'partition_key'], 'msg': 'Extra inputs are not permitted', 'input': None}
Root cause: DagOperations.trigger() in airflow-ctl/src/airflowctl/api/operations.py serializes the request body without exclude_none=True:
json=trigger_dag_run.model_dump(mode="json")
TriggerDAGRunPostBody includes partition_key and bundle_version, both added in Airflow 3.2.0's model. Since these default to None and are never excluded from serialization, every trigger request includes them as null regardless of the target server's Airflow version. Any server running < 3.2.0 doesn't recognize these fields and rejects the request entirely.
AssetsOperations.create_event() in the same file already handles this correctly:
json=asset_event_body.model_dump(mode="json", exclude_none=True)
Confirmed via the live OpenAPI schema on a 3.1.x deployment (curl .../openapi.json) that partition_key/bundle_version genuinely don't exist in that server's TriggerDAGRunPostBody schema, and confirmed directly against the apache/airflow source that these fields were added starting at the 3.2.0 tag (absent in 3.1.0 through 3.1.8).
What is the expected results?
airflowctl dags trigger should succeed against any Airflow API server version whose TriggerDAGRunPostBody schema it's compatible with, i.e., it shouldn't send fields the target server doesn't recognize just because the client's own model happens to declare them, when those fields were never explicitly set by the caller.
Anything else?
Steps to reproduce:
- Deploy Airflow 3.1.x (reproduced on 3.1.0 via Charmed Airflow on Kubernetes)
airflowctl auth login --api-url <url> --env <env> --skip-keyring
airflowctl dags trigger <dag_id> --dag-run-id <run_id> --env <env>
- Observe the
extra_forbidden error
Fix confirmed locally: adding exclude_none=True to trigger()'s model_dump() call resolves the issue, tested both with and without --logical-date passed explicitly. PR incoming with the fix plus a regression test.
Are you willing to submit PR?
Code of Conduct
Airflow CTL Version
Latest stable version
Airflow CTL Command
airflowctl dags trigger example_simplest_dag --dag-run-id <run_id> --env production
Keyring Backend / Version
Keyring Backend/Headless
Auth Type
Token
What is the current behaviour?
airflowctl dags triggerfails against any Airflow deployment running a version earlier than 3.2.0, with:{'type': 'extra_forbidden', 'loc': ['body', 'partition_key'], 'msg': 'Extra inputs are not permitted', 'input': None}
Root cause:
DagOperations.trigger()inairflow-ctl/src/airflowctl/api/operations.pyserializes the request body withoutexclude_none=True:TriggerDAGRunPostBodyincludespartition_keyandbundle_version, both added in Airflow 3.2.0's model. Since these default toNoneand are never excluded from serialization, every trigger request includes them asnullregardless of the target server's Airflow version. Any server running < 3.2.0 doesn't recognize these fields and rejects the request entirely.AssetsOperations.create_event()in the same file already handles this correctly:Confirmed via the live OpenAPI schema on a 3.1.x deployment (
curl .../openapi.json) thatpartition_key/bundle_versiongenuinely don't exist in that server'sTriggerDAGRunPostBodyschema, and confirmed directly against theapache/airflowsource that these fields were added starting at the3.2.0tag (absent in3.1.0through3.1.8).What is the expected results?
airflowctl dags triggershould succeed against any Airflow API server version whoseTriggerDAGRunPostBodyschema it's compatible with, i.e., it shouldn't send fields the target server doesn't recognize just because the client's own model happens to declare them, when those fields were never explicitly set by the caller.Anything else?
Steps to reproduce:
airflowctl auth login --api-url <url> --env <env> --skip-keyringairflowctl dags trigger <dag_id> --dag-run-id <run_id> --env <env>extra_forbiddenerrorFix confirmed locally: adding
exclude_none=Truetotrigger()'smodel_dump()call resolves the issue, tested both with and without--logical-datepassed explicitly. PR incoming with the fix plus a regression test.Are you willing to submit PR?
Code of Conduct