You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
TaskFlow AirflowSkipException causes downstream step to fail #24338
Using TaskFlow API and have 2 tasks that lead to the same downstream task. These tasks check for new data and when found will set an XCom entry of the new filename for the downstream to handle. If no data is found the upstream tasks raise a skip exception.
The downstream task has the trigger_rule = none_failed_min_one_success.
Problem is that a task which is set to Skip doesn't set any XCom. When the downstream task starts it raises the error: airflow.exceptions.AirflowException: XComArg result from task2 at airflow_2_3_xcomarg_render_error with key="return_value" is not found!
What you think should happen instead
Based on trigger rule of "none_failed_min_one_success", expectation is that an upstream task should be allowed to skip and the downstream task will still run. While the downstream does try to start based on trigger rules, it never really gets to run since the error is raised when rendering the arguments.
As a workaround, you can remove t2 from downstream_task args and check if task2 result exists in the function body. Or you can add one more task between task2 and downstream_task that will check if upstream skipped and return None or return upstream value.
I think downstream_task should be run in your case, but I'm not sure want value we expect to see in t2? None/skip exception/some_special_value_for_that_case?
We want to run either t1 or t2, or both, then combine_results the results, but if any of them are skippped we observe the same issue, XComArg result from .... with key="return_value" is not found! Previously we would get null values as input arguments if the upstream was skipped, that's not ideal either, some placeholder-value for skipped would be the best imo.
@ashb I provided additional detail in #24401 (comment) showing a more complete example of how this was being used.
In short, passing the XComArg to a downstream task was being used as it allowed the relationship between tasks to be established automatically instead of having to explicitly set these relationships through bitshift operators or calling set_upstream/set_downstream.
@ashb Previously this did return None. However, I do see that this could be indeterminant for the cases where XCom value could have been set to None or it may not have been set. Would returning the NOTSET object instead of raising an error when it is seen work better? If that is done, then the difference between XCom is None or XCom wasn't set, could be determined in the event that someone needed to be able to tell the difference between those cases.
Edit: I think the most important runtime behavior is that the XComArg.resolve method returns a value instead of raising an error. When raising an error the task won't run, even if by the trigger rules meant that it tried to run. The exact value returned, None or some sentinel value (NOTSET) that someone can check for should work, in my opinion.
Unsure if helpful - but tossing in my vote for this as well and thought to share my use case.
Expected trigger_rule would be respected rather than automatically failing downstream tasks. I have downstream task that pick a random choice from any successful upstream.
Activity
robinsinghstudios commentedon Jun 10, 2022
The same issue has been bothering me for a while now and preventing me from upgrading to the latest airflow version.
vanchaxy commentedon Jun 11, 2022
As a workaround, you can remove t2 from downstream_task args and check if task2 result exists in the function body. Or you can add one more task between task2 and downstream_task that will check if upstream skipped and return None or return upstream value.
I think downstream_task should be run in your case, but I'm not sure want value we expect to see in t2? None/skip exception/some_special_value_for_that_case?
mariotaddeucci commentedon Jun 13, 2022
I have the same issue, after upgrading from 2.1.3 to 2.3.2, some dags with the trigger rule all_done, starting to raises this exception
hterik commentedon Jun 23, 2022
Same issue when using the branchoperator, eg
We want to run either t1 or t2, or both, then combine_results the results, but if any of them are skippped we observe the same issue,
XComArg result from .... with key="return_value" is not found!Previously we would get null values as input arguments if the upstream was skipped, that's not ideal either, some placeholder-value for skipped would be the best imo.ashb commentedon Jul 5, 2022
@jordanjeremy What value would you expect to be passed to
downstream_taskfor thet2argument?jordanjeremy commentedon Jul 5, 2022
@ashb I provided additional detail in #24401 (comment) showing a more complete example of how this was being used.
In short, passing the XComArg to a downstream task was being used as it allowed the relationship between tasks to be established automatically instead of having to explicitly set these relationships through bitshift operators or calling set_upstream/set_downstream.
ashb commentedon Jul 5, 2022
@jordanjeremy That says the use case (I agree it makes sense) but not the runtime behaviour. I guess you're expecting
Noneto be passed?jordanjeremy commentedon Jul 5, 2022
@ashb Previously this did return
None. However, I do see that this could be indeterminant for the cases where XCom value could have been set to None or it may not have been set. Would returning the NOTSET object instead of raising an error when it is seen work better? If that is done, then the difference between XCom is None or XCom wasn't set, could be determined in the event that someone needed to be able to tell the difference between those cases.Edit: I think the most important runtime behavior is that the
XComArg.resolvemethod returns a value instead of raising an error. When raising an error the task won't run, even if by the trigger rules meant that it tried to run. The exact value returned, None or some sentinel value (NOTSET) that someone can check for should work, in my opinion.markhatch commentedon Jul 15, 2022
Unsure if helpful - but tossing in my vote for this as well and thought to share my use case.
Expected
trigger_rulewould be respected rather than automatically failing downstream tasks. I have downstream task that pick a random choice from any successful upstream.In the example above - would expect the
choose_clustertask to pick/passcluster_b. Instead throwskey="return_value" is not foundas mentioned.