Fix airflowctl tracebacks on an unusable credentials file - #72468
Open
Eason09053360 wants to merge 1 commit into
Open
Fix airflowctl tracebacks on an unusable credentials file#72468Eason09053360 wants to merge 1 commit into
Eason09053360 wants to merge 1 commit into
Conversation
Reading the credentials file guarded only against the file being absent, so anything else about it that stopped a command - wrong permissions, non-UTF-8 bytes, truncated JSON, the wrong shape - reached the operator as a Python stack trace. `$AIRFLOW_HOME/production.json` is a generic enough name in a shared directory that a foreign or half-written file is not far-fetched, and none of those errors were something the CLI's own handler recognised. The tolerance that lets `auth login` run without a credentials file now covers an unusable one too, so the recovery the message recommends is actually available.
Eason09053360
requested review from
bugraoz93,
dheerajturaga,
henry3260 and
potiuk
as code owners
September 3, 2026 07:44
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.
Credentials.load()guarded only against the credentials file being absent. Anythingelse that stopped it being read reached the operator as a Python stack trace, because
none of those exception types are ones
safe_call_commandrecognises:PermissionErrortracebackUnicodeDecodeErrortracebackJSONDecodeErrortracebackTypeErrortracebackapi_urlkeyKeyError: 'api_url'traceback$AIRFLOW_HOME/production.jsonis a generic name in a shared directory, so a foreignor half-written file is not far-fetched.
_read_cli_configtakes the path and owns the open, which is what puts all of thosein one place —
OSErrorcovers the unreadable paths andValueErrorcovers bothJSONDecodeErrorandUnicodeDecodeError, which are siblings rather than parent andchild.
FileNotFoundErroris re-raised untouched so the callers keep handling anabsent file as the distinct case it is. The debug-credentials read in the same
function goes through the helper too.
The tolerance that lets
auth loginrun without a credentials file now covers anunusable one as well. Without that, the error tells the operator to log in again and
the same error blocks them from doing it; the only way out was deleting the file by
hand.
safe_call_commandcatchesAirflowCtlExceptionrather than a hand-maintained tupleof five subclasses. The tuple was already equivalent to the base class, and keeping it
manual means the next exception class added anywhere regresses to a traceback — the
same failure this PR is fixing. One side effect worth noting: the path-traversal guard
in
_safe_path_under_airflow_homeraisesAirflowCtlExceptiondirectly and so was notbeing caught before; it now renders as a message instead of a traceback.
Deliberately out of scope:
{"api_url": null}still loads asNoneand letsget_clientfall back tolocalhost:8080. That is a silently-wrong-server bug ratherthan a traceback,
Credentials.save()itself writes such a file, and an existing testcovers the current behaviour — it wants its own change.
auth list-envsalso reads thesame file through its own logic, which now defines "unusable" slightly differently.
Was generative AI tooling used to co-author this PR?
Generated-by: Claude Code (Opus 5) following the guidelines