Repository navigation
Reject unsupported output_type and bound HITL XCom pull retries - #74450
Merged
Merged
Conversation
kaxil
reviewed
Oct 8, 2026
kaxil
approved these changes
Oct 8, 2026
1 task done
…forever on XCom errors LLMBranchOperator now raises TypeError when output_type is passed instead of silently dropping it, since the operator builds the output type from its downstream task IDs. The HITL review loop re-raises the XCom pull error after 10 consecutive failures, so a task with hitl_timeout=None no longer spins forever when the API server is unreachable. When hitl_timeout is set, persistent XCom failures now raise the original error on the 10th failure instead of waiting for the deadline to raise HITLTimeoutError. LLMOperator's output_type annotation now matches pydantic-ai's OutputSpec, accepting union and list forms as well as plain types.
- `output_type` is annotated as `type | UnionType` instead of `OutputSpec[Any]`, so list forms such as `[A, B]` and marker forms such as `ToolOutput(A)` are no longer advertised; they cannot be rehydrated when `require_approval=True` resumes the task - the `output_type` parameter docs describe the accepted shapes
- the HITL review loop logs an error with the failure count before it re-raises the XCom pull error, so the task log shows the loop gave up rather than a one-off failure - the `HITLReviewMixin` docstring, `run_hitl_review` `:raises:`, `hitl_review.rst` and the `AgentOperator` `hitl_timeout` docs no longer say `hitl_timeout=None` blocks until a terminal action
- passing `output_type` to `LLMSQLQueryOperator` or `LLMSchemaCompareOperator` (or their `@task.llm_sql` / `@task.llm_schema_compare` forms) raises `TypeError` instead of being silently dropped or overwritten, matching `LLMBranchOperator` - mapped tasks (`.partial()` / `.expand()`) raise when the task is unmapped on the worker
Lee-W
force-pushed
the
common-ai-operators-fixes
branch
from
October 9, 2026 04:54
117eea3 to
f663106
Compare
This was referenced Oct 14, 2026
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.
Why
LLMBranchOperatorbuilds its output type from its downstream task IDs, but it silently dropped anyoutput_typethe caller passed (kwargs.pop("output_type", None)). A user who sets it gets no signal that it has no effect.run_hitl_reviewswallowedxcom_pullerrors with a warning and kept polling. Sincehitl_timeoutcan beNone, persistent failures (for example an unreachable API server) made the task spin forever.LLMOperator.output_typewas annotated astype, which is narrower than what pydantic-ai accepts.What
LLMBranchOperator: passingoutput_typenow raisesTypeErrorinstead of being silently dropped. This is a behaviour change: callers who passed it before (and had it rror.mixins/hitl_review.py): added_MAX_CONSECUTIVE_XCOM_PULL_FAILURES = 10and aconsecutive_pull_failurescounter in therun_hitl_reviewloop. Each `xcom_pit. On the 10th consecutive failure the originalexception is re-raised unchanged. Otherwise it logs a warning and continues. A successful pull resets the counter to 0.hitl_timeoutis set, persistent XCom faial error on the 10th failure instead of waiting forthe deadline and raisingHITLTimeoutError. -LLMOperator:output_type: type = strbecomes ny] = str, withOutputSpecimported frompydantic_ai.outputunderTYPE_CHECKING`. This accepts union and list forms, ma- Tests:test_hitl_review.py: addedtest_xcom_pull_failures_raise_after_limitandtest_xcom_pull_failure_counter_resets_on_success.test_llm_branch.py:test_output_type_ignoredbecomestest_output_type_rejected.Was generative AI tooling used to co-author this PR?
Generated-by: [Claude] following the guidelines
{pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.