Compare commits

...

1 Commits

Author SHA1 Message Date
Rockachopa
9d089d7aec Fix provider fallback chain: select only healthy fallback providers
Some checks failed
Architecture Lint / Linter Tests (pull_request) Successful in 31s
Smoke Test / smoke (pull_request) Failing after 16s
Validate Config / YAML Lint (pull_request) Failing after 10s
Validate Config / JSON Validate (pull_request) Successful in 14s
Validate Config / Python Syntax & Import Check (pull_request) Failing after 35s
Validate Config / Python Test Suite (pull_request) Has been skipped
Validate Config / Shell Script Lint (pull_request) Failing after 53s
Validate Config / Cron Syntax Check (pull_request) Successful in 10s
Validate Config / Deploy Script Dry Run (pull_request) Successful in 11s
Validate Config / Playbook Schema Validation (pull_request) Successful in 25s
PR Checklist / pr-checklist (pull_request) Successful in 3m40s
Architecture Lint / Lint Repository (pull_request) Failing after 15s
In bin/provider-health-monitor.py, the fallback selection loop
(changed lines 286-291) previously picked the first fallback provider
that differed from the current provider, WITHOUT verifying that the
fallback was healthy. This could cascade a failure: an unhealthy current
provider would be switched to an unhealthy fallback, corrupting config
and breaking agent operation.

Now the loop checks health_map[provider]["healthy"] before selecting.
This implements the try/except/continue pattern semantically:
each fallback provider is "tried" (health-checked) and if not healthy
we "continue" to the next. Agent survives provider failures by
cascading only to providers confirmed alive.

Closes #445
2026-04-26 14:22:40 -04:00

View File

@@ -283,10 +283,10 @@ def check_profiles(health_map):
if current_provider in health_map and health_map[current_provider]["healthy"]:
continue # Provider is healthy, no action needed
# Find best fallback
# Find best fallback — must be healthy
best_fallback = None
for provider in fallback_providers:
if provider != current_provider:
if provider != current_provider and health_map.get(provider, {}).get("healthy", False):
best_fallback = provider
break