Let BashOperator push multiple XComs, including on failure - #72546
Draft
dheerajturaga wants to merge 2 commits into
Draft
Let BashOperator push multiple XComs, including on failure#72546dheerajturaga wants to merge 2 commits into
dheerajturaga wants to merge 2 commits into
Conversation
A Bash task could only ever produce one XCom: the last line written to stdout. Anything richer meant serialising to JSON on a single line and parsing it back with output_processor, which drags shell authors into quote-escaping for even simple key/value pairs -- the KubernetesPodOperator sidecar has the same contract, and every example of it in this repo writes a JSON literal rather than a shell variable, which is telling. Worse, the task runner only pushes XCom on the success path, so a failing command could not hand any diagnostic data to downstream tasks or to the UI, which is precisely when that data is most wanted. Handing the script a directory instead of parsing its stdout takes the format out of the contract altogether: the filename is the key, so no value needs escaping no matter what it contains, and size and newlines stop mattering. Reading that directory back from a finally block is what makes the failure case work. Nesting values via subdirectories was considered and deliberately left out. A ".json" file already covers structured values, and nesting can be added in a later release without breaking anyone -- whereas removing it once released could not.
The XCom directory section was the only part of the Bash guide that showed just one flavour, while every other section on the page offers both. A TaskFlow author reading it had no way to tell the mechanism applies to them too, since it is inherited rather than spelled out anywhere.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A Bash task can only produce one XCom today: the last line written to stdout. Anything richer means serialising to JSON on a single line and parsing it back with
output_processor, which drags shell authors into quote-escaping for even simple key/value pairs. TheKubernetesPodOperatorsidecar has the same JSON contract, and every example of it in this repo writes a JSON literal rather than a shell variable — which is telling.Separately, the task runner only pushes XCom on the success path (
_push_xcom_if_needed), so a failing command cannot hand any diagnostic data to downstream tasks or to the UI — precisely when that data is most wanted.What this adds
When
do_xcom_pushis set,BashOperatorexposes a directory as$AIRFLOW_XCOM_DIRplus anxcom pushhelper onPATH, and reads the directory back in afinallyblock — so entries are pushed whether the command succeeded, failed, or skipped.Two rules govern what becomes an XCom:
.jsonsuffix parses the content and drops the suffix from the key.Because the filename carries the key, there is no format to escape — the value can contain quotes, spaces, or newlines and still round-trips. The helper is sugar over the documented directory contract, so scripts that reset
PATHor exec into a container can just redirect into$AIRFLOW_XCOM_DIR.If the script writes a
return_valueentry and the command succeeds, that value is returned fromexecute()rather than the stdout last line, so it flows through the runner's normal return-value push and composes withmultiple_outputs=True.Was generative AI tooling used to co-author this PR?
Generated-by: Claude Code (Opus 5) following the guidelines
🤖 Generated with Claude Code
https://claude.ai/code/session_01SPiZuBWUwhduTb3JdNYzsN