From c514f712f48cf928176c6d982b3a017e97147f04 Mon Sep 17 00:00:00 2001 From: Ahmed Allam Date: Wed, 2 Sep 2026 13:02:09 +0000 Subject: [PATCH] fix(config): persist only the alias the runtime settings read pydantic-settings takes the first alias present in the environment, even when it is empty. persist_current() must save that same alias, so an empty LLM_API_KEY does not let a non-empty OPENAI_API_KEY sibling land in the file and restore a credential the run did not use. --- strix/config/loader.py | 11 ++++------- tests/test_config_loader.py | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/strix/config/loader.py b/strix/config/loader.py index 250790c6..e6edd548 100644 --- a/strix/config/loader.py +++ b/strix/config/loader.py @@ -79,16 +79,13 @@ def persist_current() -> None: continue for finfo in type(sub_model).model_fields.values(): aliases = [alias.upper() for alias in _aliases_for(finfo)] - set_aliases = [alias for alias in aliases if os.environ.get(alias) is not None] - if not set_aliases: + active = next((alias for alias in aliases if alias in os.environ), None) + if active is None: continue for alias in aliases: env_block.pop(alias, None) - for alias in set_aliases: - value = os.environ[alias] - if value: - env_block[alias] = value - break + if os.environ[active]: + env_block[active] = os.environ[active] write_secret_text(target, json.dumps({"env": env_block}, indent=2)) diff --git a/tests/test_config_loader.py b/tests/test_config_loader.py index c370f8eb..d4bc7ba5 100644 --- a/tests/test_config_loader.py +++ b/tests/test_config_loader.py @@ -364,6 +364,22 @@ def test_persist_current_empty_env_clears_file_value( assert json.loads(target.read_text(encoding="utf-8")) == {"env": {"STRIX_LLM": "file-model"}} +def test_persist_current_empty_primary_alias_does_not_save_sibling( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + target = tmp_path / "cli-config.json" + target.write_text(json.dumps({"env": {"PERPLEXITY_API_KEY": "pplx"}}), encoding="utf-8") + loader.apply_config_override(target) + monkeypatch.setenv("LLM_API_KEY", "") + monkeypatch.setenv("OPENAI_API_KEY", "sibling-key") + + assert loader.load_settings().llm.api_key == "" + + loader.persist_current() + + assert json.loads(target.read_text(encoding="utf-8")) == {"env": {"PERPLEXITY_API_KEY": "pplx"}} + + def test_persist_current_replaces_corrupt_file( tmp_path: Path, monkeypatch: pytest.MonkeyPatch ) -> None: