Skip to content

Accept BLOCKED and WAITING_FOR_RETRY Databricks run states - #69193

Merged
amoghrajesh merged 2 commits into
apache:mainfrom
astronomer:databricks-fix-blocked-state
Jul 1, 2026
Merged

Accept BLOCKED and WAITING_FOR_RETRY Databricks run states#69193
amoghrajesh merged 2 commits into
apache:mainfrom
astronomer:databricks-fix-blocked-state

Conversation

@amoghrajesh

Copy link
Copy Markdown
Contributor

Was generative AI tooling used to co-author this PR?
  • Yes

Forked off of: #69174

What

RunState (the class that parses a Databricks run state) raises AirflowException("Unexpected life cycle state") for any life-cycle state outside its hardcoded RUN_LIFE_CYCLE_STATES allowlist. That allowlist is a hand maintained duplicate of the RunLifeCycleState enum and has drifted: it is missing BLOCKED and WAITING_FOR_RETRY, both of which the enum (and the Databricks API) define.

Why it matters

BLOCKED and WAITING_FOR_RETRY are normal in-flight states:

  • BLOCKED - the run cannot start yet because it is gated (max concurrent runs, a dependency, queueing). Routine for DatabricksRunNowOperator, which triggers existing jobs that are often concurrency- or dependency-gated.
  • WAITING_FOR_RETRY - a task failed and Databricks is waiting to retry it.

Because RunState rejects them, an operator polling a run that enters either state fails with AirflowException instead of continuing to wait. This affects the normal (synchronous) poll loop and get_run_state for both DatabricksSubmitRunOperator and DatabricksRunNowOperator, on clean runs today - no crash or retry required to hit it.

Fix

Add BLOCKED and WAITING_FOR_RETRY to RunState.RUN_LIFE_CYCLE_STATES so they parse as valid states. No change to is_terminal: it already lists only TERMINATED/SKIPPED/INTERNAL_ERROR, so both new states are correctly treated as non-terminal and the poll loop keeps waiting until the run actually finishes.

Backcompat

No behavior change other than not crashing: a run in one of these two states is now parsed and polled through instead of raising. Nothing that previously succeeded changes. The strict "unknown state raises" behavior is retained for genuinely unrecognized states.


  • Read the Pull Request Guidelines for more information. Note: commit author/co-author name and email in commits become permanently public when merged.
  • For fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
  • When adding dependency, check compliance with the ASF 3rd Party License Policy.
  • For significant user-facing changes create newsfragment: {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.

@jason810496 jason810496 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice catch!

Comment thread providers/databricks/src/airflow/providers/databricks/hooks/databricks.py Outdated
…tabricks.py

Co-authored-by: Jason(Zhe-You) Liu <68415893+jason810496@users.noreply.github.com>
@uranusjr

uranusjr commented Jul 1, 2026

Copy link
Copy Markdown
Member

Got this from Claude:

The root cause is two sources of truth for the same set: the RunLifeCycleState enum and the hand-maintained RUN_LIFE_CYCLE_STATES list. This PR patches the symptom (adds the two missing values) but leaves the duplication in place, so the list can silently drift again the next time Databricks adds a state.

Since the enum is already the canonical definition, deriving the allowlist from it would make this class of bug structurally impossible:

class RunState:
    RUN_LIFE_CYCLE_STATES = frozenset(s.value for s in RunLifeCycleState)

This aligns with Airflow's preference for a single source of truth over hand-maintained > parallel lists. It's equivalent to the current post-fix list (verified: same 9 members) > and would prevent recurrence. Reasonable to do here or leave as a small follow-up — not a merge blocker.

Not sure how doable this is, but leaving it here just in case.

@amoghrajesh

Copy link
Copy Markdown
Contributor Author

I'll take a look at that in a follow up, @uranusjr

@amoghrajesh
amoghrajesh merged commit a3f51fc into apache:main Jul 1, 2026
81 checks passed
@github-project-automation github-project-automation Bot moved this from In progress to Done in Durable / Crash-Safe Execution Jul 1, 2026
@amoghrajesh
amoghrajesh deleted the databricks-fix-blocked-state branch July 1, 2026 07:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Development

Successfully merging this pull request may close these issues.

4 participants