This is an automated email from the ASF dual-hosted git repository.
shahar1 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new ec8737c5417 Handle empty or corrupted JSON in airflowctl credentials
loading (#75279)
ec8737c5417 is described below
commit ec8737c5417787d2f9c3f1ea9e26e6bfcd6c563b
Author: Jarek Potiuk <[email protected]>
AuthorDate: Tue Oct 27 05:52:55 2026 +0100
Handle empty or corrupted JSON in airflowctl credentials loading (#75279)
---
airflow-ctl/src/airflowctl/api/client.py | 3 ++-
airflow-ctl/tests/airflow_ctl/api/test_client.py | 11 +++++++++++
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/airflow-ctl/src/airflowctl/api/client.py
b/airflow-ctl/src/airflowctl/api/client.py
index da8e364a786..b1772747346 100644
--- a/airflow-ctl/src/airflowctl/api/client.py
+++ b/airflow-ctl/src/airflowctl/api/client.py
@@ -298,9 +298,10 @@ class Credentials:
if self.client_kind == ClientKind.CLI:
raise AirflowCtlKeyringException("Keyring backend
is not available") from e
self.api_token = None
- except FileNotFoundError:
+ except (FileNotFoundError, json.JSONDecodeError):
# This is expected during the auth login command.
# Also allow token-only usage without local config (for commands
like `version --remote`).
+ # JSONDecodeError handles the case where the credentials file
exists but is empty or corrupted.
if self.client_kind not in (ClientKind.AUTH, ClientKind.NO_AUTH)
and self.api_token is None:
raise AirflowCtlCredentialNotFoundException("No credentials
file found. Please login first.")
diff --git a/airflow-ctl/tests/airflow_ctl/api/test_client.py
b/airflow-ctl/tests/airflow_ctl/api/test_client.py
index dadf5d80367..df104786dab 100644
--- a/airflow-ctl/tests/airflow_ctl/api/test_client.py
+++ b/airflow-ctl/tests/airflow_ctl/api/test_client.py
@@ -362,6 +362,17 @@ class TestCredentials:
assert not os.path.exists(config_dir)
+ @patch.dict(os.environ, {"AIRFLOW_CLI_ENVIRONMENT":
"TEST_EMPTY_CREDENTIALS"})
+ @patch("airflowctl.api.client.keyring")
+ def test_load_empty_or_corrupt_credentials(self, mock_keyring):
+ cli_client = ClientKind.CLI
+ config_dir = os.environ.get("AIRFLOW_HOME",
os.path.expanduser("~/airflow"))
+ os.makedirs(config_dir, exist_ok=True)
+ with open(os.path.join(config_dir, "TEST_EMPTY_CREDENTIALS.json"),
"w") as f:
+ f.write("")
+ with pytest.raises(AirflowCtlCredentialNotFoundException, match="No
credentials file found"):
+ Credentials(client_kind=cli_client).load()
+
@patch.dict(os.environ, {"AIRFLOW_CLI_ENVIRONMENT":
"TEST_NO_CONFIG_WITH_EXPLICIT_TOKEN"})
@patch("airflowctl.api.client.keyring")
def test_load_no_config_with_explicit_token(self, mock_keyring):