fix(ui): fetch version + debug flag from /health/readiness/details (backport #27896) - #27899
Conversation
The proxy moved `litellm_version`, `is_detailed_debug`, and other diagnostic fields off the public `/health/readiness` payload behind an auth-gated `/health/readiness/details` endpoint. The navbar version tag and the detailed-debug-mode banner stopped working because they were still reading those fields from the unauthed response, which no longer contains them. Replace `useHealthReadiness` with a `useHealthReadinessDetails` hook that takes an `accessToken` argument and sends a Bearer header to the auth-gated endpoint. The hook stays disabled while `accessToken` is falsy, so the navbar can keep rendering on the public model hub (where the token is null) without triggering an auth redirect or a 401-loop.
Two small follow-ups on the readiness/details migration: - Set `retry: false` on the query. The payload feeds a passive navbar tag and a debug banner; a 401 from an expired token shouldn't fan out into three retries against the proxy. - Add navbar specs that assert the `accessToken` prop is forwarded into the hook (matches the DebugWarningBanner spec). Without this, the navbar could silently regress to passing `undefined` and the existing tests wouldn't catch it.
Greptile SummaryThis backport wires the UI to the new auth-gated
Confidence Score: 4/5Safe to merge — the change is a clean hook swap with no logic regressions; test coverage is maintained and extended. The hook correctly gates requests on token availability and disables retries for display-only data. Two minor style/design points: a ui/litellm-dashboard/src/app/(dashboard)/hooks/healthReadiness/useHealthReadinessDetails.ts — the new hook has the
|
| Filename | Overview |
|---|---|
| ui/litellm-dashboard/src/app/(dashboard)/hooks/healthReadiness/useHealthReadinessDetails.ts | New auth-gated hook replacing useHealthReadiness; correctly disables when token is falsy and sets retry: false. Minor: Content-Type header on a GET request; static query key doesn't include the token. |
| ui/litellm-dashboard/src/components/navbar.tsx | Switches from useHealthReadiness() to useHealthReadinessDetails(accessToken), forwarding the token already present in NavbarProps. Change is minimal and correct. |
| ui/litellm-dashboard/src/components/DebugWarningBanner.tsx | Adds accessToken prop and passes it to the new hook; interface is well-typed and the component logic is unchanged. |
| ui/litellm-dashboard/src/app/(dashboard)/layout.tsx | One-line change to pass accessToken to DebugWarningBanner; accessToken is already available in scope from useAuthorized(). |
| ui/litellm-dashboard/src/components/navbar.test.tsx | Updates mocks to the new hook and adds two new specs that assert accessToken is forwarded (both truthy and null cases). Tests are meaningful and not weakened. |
| ui/litellm-dashboard/src/components/DebugWarningBanner.test.tsx | All existing test cases updated to the new hook and new prop; two new specs added to verify token forwarding. Coverage is maintained and not weakened. |
Reviews (1): Last reviewed commit: "fix(ui): disable retries on readiness/de..." | Re-trigger Greptile
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
| headers: { | ||
| [getGlobalLitellmHeaderName()]: `Bearer ${accessToken}`, | ||
| "Content-Type": "application/json", | ||
| }, |
There was a problem hiding this comment.
Sending
Content-Type: application/json on a GET request is semantically incorrect — GET requests carry no body, so the content type is meaningless. Most servers ignore it, but it can confuse some middleware or proxies and differs from how the old fetchHealthReadiness function (no Content-Type) made the same kind of request.
| headers: { | |
| [getGlobalLitellmHeaderName()]: `Bearer ${accessToken}`, | |
| "Content-Type": "application/json", | |
| }, | |
| headers: { | |
| [getGlobalLitellmHeaderName()]: `Bearer ${accessToken}`, | |
| }, |
| return useQuery<HealthReadinessDetailsResponse>({ | ||
| queryKey: healthReadinessDetailsKeys.detail("readiness"), | ||
| queryFn: () => fetchHealthReadinessDetails(accessToken!), |
There was a problem hiding this comment.
The query key is static and does not include
accessToken. Both Navbar and DebugWarningBanner will deduplicate to this single cache entry, which is intentional, but it also means that if the token changes (e.g., a session refresh or a different user logs in within the 5-minute staleTime window) the old cached response will be served without re-fetching. Since /health/readiness/details returns server-wide state (not per-user data), this is unlikely to cause incorrect behavior today, but the /details endpoint is auth-scoped — including the token in the key (e.g. healthReadinessDetailsKeys.detail("readiness", accessToken)) would guarantee a fresh fetch on token rotation.
Summary
Backport of #27896 onto
litellm_1.84.0rc2.Pairs with the backend backport #27868 which moved
litellm_version,is_detailed_debug, and other diagnostic fields off the public/health/readinesspayload behind the auth-gated/health/readiness/detailsendpoint. Without this UI backport, the rc2 navbar version tag and detailed-debug-mode banner silently stop rendering because the hook is still reading those fields from the public endpoint.Contents
Two commits cherry-picked from staging:
21b399f68a— replaceuseHealthReadinesswithuseHealthReadinessDetails, which takesaccessTokenas an arg, sendsAuthorization: Bearer <token>, and stays disabled when the token is falsy so the public model hub (where the token is null) keeps rendering without an auth redirect or 401 loop.4f7e7d8cd2— setretry: falseon the query (a passive display surface shouldn't fan out into three retries on an expired-token 401) and add navbar specs asserting theaccessTokenprop is forwarded to the hook.Behavior delta worth noting
Anonymous visitors to the public model hub on rc2 will no longer see the version tag in the navbar. That's the intended consequence of #26912 / #27866 / #27868 — version info is now considered recon-sensitive and only exposed to authenticated callers. The UI is complying with the backend's contract rather than working around it.
Test plan
git ls-treeblob SHAs).vitest runfor the two impacted suites passes 20/20.