Skip to content

Fix airflowctl tracebacks on an unusable credentials file - #72468

Open
Eason09053360 wants to merge 1 commit into
apache:mainfrom
Eason09053360:fix-airflowctl-unreadable-credentials-traceback
Open

Fix airflowctl tracebacks on an unusable credentials file#72468
Eason09053360 wants to merge 1 commit into
apache:mainfrom
Eason09053360:fix-airflowctl-unreadable-credentials-traceback

Conversation

@Eason09053360

Copy link
Copy Markdown
Contributor

Credentials.load() guarded only against the credentials file being absent. Anything
else that stopped it being read reached the operator as a Python stack trace, because
none of those exception types are ones safe_call_command recognises:

file state before
wrong permissions PermissionError traceback
non-UTF-8 bytes UnicodeDecodeError traceback
truncated or empty JSONDecodeError traceback
valid JSON, wrong shape TypeError traceback
no api_url key KeyError: 'api_url' traceback

$AIRFLOW_HOME/production.json is a generic name in a shared directory, so a foreign
or half-written file is not far-fetched.

_read_cli_config takes the path and owns the open, which is what puts all of those
in one place — OSError covers the unreadable paths and ValueError covers both
JSONDecodeError and UnicodeDecodeError, which are siblings rather than parent and
child. FileNotFoundError is re-raised untouched so the callers keep handling an
absent 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 login run without a credentials file now covers an
unusable 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_command catches AirflowCtlException rather than a hand-maintained tuple
of 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_home raises AirflowCtlException directly and so was not
being caught before; it now renders as a message instead of a traceback.

Deliberately out of scope: {"api_url": null} still loads as None and lets
get_client fall back to localhost:8080. That is a silently-wrong-server bug rather
than a traceback, Credentials.save() itself writes such a file, and an existing test
covers the current behaviour — it wants its own change. auth list-envs also reads the
same file through its own logic, which now defines "unusable" slightly differently.


Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 5)

Generated-by: Claude Code (Opus 5) following the guidelines

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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant