Skip to content

fix(ui): send router_settings list/dict fields as JSON, surface save errors#12

Open
shivshekhar12 wants to merge 1 commit into
fix/users/shiv/save-retry-policyfrom
fix/users/shiv/router-settings-save-422
Open

fix(ui): send router_settings list/dict fields as JSON, surface save errors#12
shivshekhar12 wants to merge 1 commit into
fix/users/shiv/save-retry-policyfrom
fix/users/shiv/router-settings-save-422

Conversation

@shivshekhar12

Copy link
Copy Markdown
Collaborator

Summary

Fixes the Admin UI Router Settings → "Reliability & Retries" section, where saving any value (Allowed Fails, Cooldown Time, Timeout, Retry After, etc.) silently did nothing.

Root cause: the form rendered every field as a plain text input, so the routing_groups List field was POSTed to /config/update as the string "[]" instead of the array []. The backend validates the whole router_settings body at once, so that one malformed field caused a 422 (routing_groups -> "Input should be a valid list") that rejected the entire payload — dropping every other field in the section. The save handler also didn't await the request, so the 422 was swallowed and a success toast always showed.

Fix (frontend only, router_settings/index.tsx):

  • Parse List/Dictionary fields back into real JSON before sending (driven by field_type metadata from /router/settings), so routing_groups goes out as [].
  • await the save call: show success only on success; surface the real backend error via NotificationsManager.fromBackend on failure.

Note: this is the frontend half of the "retry_policy won't save" problem. It is stacked on the backend retry_policy PR (base branch) — end-to-end, retry_policy needs both a valid payload (this PR) and backend persistence (base PR).

Test plan

  • Backend unit (tests/test_litellm/types/test_router_types.py): UpdateRouterConfig rejects "[]", accepts [], parses populated entries.
  • Backend functional (tests/.../proxy_server/test_config_update_routing_groups.py): ConfigYAML rejects the string; POST /config/update returns 422 for "[]" and 200 for [] with a real list persisted; full Reliability & Retries payload round-trips (backward compatibility).
  • UI functional (router_settings/index.test.tsx): payload sends routing_groups as an array; failed save surfaces error and shows no success.
  • UI backward-compatibility: number/retry_policy/model_group_alias/boolean fields still serialize correctly.
  • Targeted UI suite: 51 passed. Full UI suite: 3837 passed / 381 files (no app-wide regressions). Backend: 10 passed.

Made with Cursor

…errors

The Router Settings "Reliability & Retries" form rendered every field as a
text input, so the routing_groups List field was POSTed to /config/update as
the string "[]". The backend rejected it with a 422 (routing_groups -> "Input
should be a valid list"), which invalidated the entire router_settings body
and silently dropped every other field (allowed_fails, cooldown_time,
timeout, ...). The save handler also did not await the request, so the error
was swallowed and a success toast was always shown.

- Parse List/Dictionary fields back into real JSON before sending, driven by
  the field_type metadata from /router/settings.
- Await the save call: show success only on success, surface backend errors
  via NotificationsManager.fromBackend.

Adds UI functional tests (array serialization + error surfacing), backend
unit tests for UpdateRouterConfig.routing_groups, and functional tests for
POST /config/update (422 on string, 200 + persisted list).

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant