From 51cce993995b40b223fe8fec19f12f2350193dfe Mon Sep 17 00:00:00 2001 From: ryan-crabbe-berri Date: Sat, 25 Jul 2026 09:18:20 -0700 Subject: [PATCH] fix(ui): resolve tab slug against the last base-segment match createTabRoutes.slugFromPathname matched the first occurrence of the route base segment. When SERVER_ROOT_PATH repeats that segment (e.g. /logs mounts the UI at /logs/ui, so the audit tab is /logs/ui/logs/audit/), it read the server-root copy and returned the wrong segment, which the layout treats as an unknown tab and hard-redirects to a path that misparses the same way, causing a reload loop. Match the last occurrence instead: the route base always follows any server-root prefix, and no tab slug equals the base, so the last match is always the real route base. --- ui/litellm-dashboard/src/utils/tabRoutes.test.ts | 5 +++++ ui/litellm-dashboard/src/utils/tabRoutes.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ui/litellm-dashboard/src/utils/tabRoutes.test.ts b/ui/litellm-dashboard/src/utils/tabRoutes.test.ts index 402be55c33a..7165b67addc 100644 --- a/ui/litellm-dashboard/src/utils/tabRoutes.test.ts +++ b/ui/litellm-dashboard/src/utils/tabRoutes.test.ts @@ -25,6 +25,11 @@ describe("createTabRoutes.slugFromPathname", () => { it("returns empty string when the base segment is not in the path", () => { expect(routes.slugFromPathname("/teams")).toBe(""); }); + + it("reads the route base after a server-root prefix that repeats the segment name", () => { + expect(routes.slugFromPathname("/logs/ui/logs/audit/")).toBe("audit"); + expect(routes.slugFromPathname("/logs/ui/logs/")).toBe(""); + }); }); describe("createTabRoutes.tabHref", () => { diff --git a/ui/litellm-dashboard/src/utils/tabRoutes.ts b/ui/litellm-dashboard/src/utils/tabRoutes.ts index f27b1f5d49f..ecd52250556 100644 --- a/ui/litellm-dashboard/src/utils/tabRoutes.ts +++ b/ui/litellm-dashboard/src/utils/tabRoutes.ts @@ -15,7 +15,7 @@ export function createTabRoutes(baseSegment: string, slugs: const slugFromPathname = (pathname: string): string => { const parts = pathname.split("/").filter(Boolean); - const idx = parts.indexOf(baseSegment); + const idx = parts.lastIndexOf(baseSegment); if (idx === -1) { return ""; }