Skip to content

Commit be0b6b2

Browse files
lolimmlostclaude
andcommitted
fix: Strip section prefix from env-var keys so WEB_* settings actually load
_load_from_env stored env-var keys lowercased verbatim, so WEB_HOST became {"web": {"web_host": ...}} while Web.__init__ reads web_config.get("host", ...). Result: WEB_ENABLED, WEB_HOST, WEB_PORT, WEB_DB_PATH all silently no-op'd when configured via environment variables — the values were loaded into the dict but under keys nothing actually reads. PROXY_PREFIX was the only web env var that worked, because its name doesn't start with the WEB_ prefix. Practical impact: env-var deployments could not change the listen address, port, database path, or even disable the web UI — every WEB_ENABLED=false ran the UI anyway. Verified empirically before fix. Strip the section-name prefix from env-var keys when storing in _load_from_env so they match the YAML schema. This is surgical: no other section uses an env-var prefix matching its name, so the behavior of general/jobs/instances/download_clients is unchanged. Add a parametrized regression test covering all five web env vars, including a value (WEB_ENABLED=false) that differs from the default so a no-op fix would be caught. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 4faf5cf commit be0b6b2

2 files changed

Lines changed: 19 additions & 1 deletion

File tree

src/settings/_user_config.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ def _load_from_env() -> dict:
8181

8282
for section, keys in CONFIG_MAPPING.items():
8383
section_config = {}
84+
# Some env vars are prefixed with the section name to keep deployment
85+
# docs unambiguous (e.g. WEB_HOST vs the bare HOST). Strip that prefix
86+
# when storing so the resulting keys match the YAML schema (`host`,
87+
# not `web_host`) and downstream classes find them.
88+
section_prefix = section.upper() + "_"
8489

8590
for key in keys:
8691
env_key = key if os.getenv(key) is not None else key.lower()
@@ -96,7 +101,8 @@ def _load_from_env() -> dict:
96101
f"Failed to parse environment variable {key} as YAML:\n{e}",
97102
)
98103
parsed_value = {}
99-
section_config[key.lower()] = parsed_value
104+
stored_key = key[len(section_prefix):] if key.startswith(section_prefix) else key
105+
section_config[stored_key.lower()] = parsed_value
100106

101107
config[section] = section_config
102108

tests/settings/test_user_config_from_env.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ def fixture_env_vars():
8787
"RADARR": radarr_yaml,
8888
"SONARR": sonarr_yaml,
8989
"QBITTORRENT": qbit_yaml,
90+
"WEB_ENABLED": "false",
91+
"WEB_HOST": "127.0.0.1",
92+
"WEB_PORT": "8080",
93+
"PROXY_PREFIX": "decluttarr",
94+
"WEB_DB_PATH": "/data/custom.db",
9095
}
9196
with patch.dict(os.environ, env, clear=True):
9297
yield env
@@ -119,6 +124,13 @@ def fixture_env_vars():
119124
("instances", "radarr", radarr_expected),
120125
("instances", "sonarr", sonarr_expected),
121126
("download_clients", "qbittorrent", qbit_expected),
127+
# Web env vars: section prefix (WEB_) is stripped on load so the keys
128+
# match the YAML schema. PROXY_PREFIX has no prefix and stays as-is.
129+
("web", "enabled", False),
130+
("web", "host", "127.0.0.1"),
131+
("web", "port", 8080),
132+
("web", "proxy_prefix", "decluttarr"),
133+
("web", "db_path", "/data/custom.db"),
122134
],
123135
)
124136
def test_env_loading_parametrized(

0 commit comments

Comments
 (0)