fix(router): guard retry_policy type in update_settings

Mirror Router.__init__ semantics in update_settings: only assign
retry_policy when it is None or a RetryPolicy (after dict coercion).
Previously a non-dict, non-RetryPolicy value (e.g. a YAML typo like
retry_policy: 5 flowing through /config/update) was stored verbatim,
deferring the failure to request time in get_num_retries_from_retry_policy
instead of being dropped at write time.
This commit is contained in:
ryan-crabbe-berri 2026-06-02 17:41:07 -07:00
parent fca8d02ce1
commit 965c964f51
2 changed files with 20 additions and 1 deletions

View file

@ -10217,7 +10217,8 @@ class Router:
value = kwargs[var]
if isinstance(value, dict):
value = RetryPolicy(**value)
setattr(self, var, value)
if value is None or isinstance(value, RetryPolicy):
setattr(self, var, value)
else:
value = kwargs[var]
# only run routing strategy init if it has changed

View file

@ -114,6 +114,24 @@ def test_update_settings_accepts_retry_policy_object_unchanged():
assert router.retry_policy is policy
def test_update_settings_ignores_malformed_retry_policy():
"""A non-dict, non-``RetryPolicy`` value (e.g. a YAML typo like
``retry_policy: 5`` reaching ``update_settings``) must not land on
``self.retry_policy``. ``Router.__init__`` already drops such inputs;
the update path must match so a malformed config can't store garbage
that ``get_num_retries_from_retry_policy`` would only choke on at
request time."""
router = _build_router()
existing = RetryPolicy(BadRequestErrorRetries=4)
router.update_settings(retry_policy=existing)
assert router.retry_policy is existing
for bad_value in (5, "RateLimitErrorRetries=7", ["BadRequestErrorRetries"]):
router.update_settings(retry_policy=bad_value)
assert router.retry_policy is existing
def test_update_settings_get_settings_round_trip_for_retry_policy():
"""``GET /get/config/callbacks`` serializes ``llm_router.get_settings()``
back to the UI. After updating, the round-trip must reflect the new