From c98d454db9671318c61120f03ecfa5c81212d1f2 Mon Sep 17 00:00:00 2001 From: jesus Date: Wed, 21 Oct 2026 00:48:14 +0000 Subject: [PATCH] fix(ui): fall back when /v2/user/info returns a different user id Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../(dashboard)/hooks/users/useUsers.test.ts | 17 +++++++++++++++++ .../src/app/(dashboard)/hooks/users/useUsers.ts | 11 +++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/ui/litellm-dashboard/src/app/(dashboard)/hooks/users/useUsers.test.ts b/ui/litellm-dashboard/src/app/(dashboard)/hooks/users/useUsers.test.ts index 70b818a8be4..6c806613f21 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/hooks/users/useUsers.test.ts +++ b/ui/litellm-dashboard/src/app/(dashboard)/hooks/users/useUsers.test.ts @@ -330,6 +330,23 @@ describe("useUserLookup", () => { expect(result.current.data?.user_id).toBe("user-1-0"); }); + it("falls back when user info returns a different user id", async () => { + const response = buildUserListResponse(1, 1); + const exactUser = { ...response.users[0], user_id: "a b", user_alias: "Right User" }; + vi.mocked(userGetInfoV2).mockResolvedValue(buildUserInfoV2Response("a+b")); + vi.mocked(userListCall).mockResolvedValue({ + ...response, + page_size: 100, + users: [exactUser], + }); + + const { result } = renderHook(() => useUserLookup("a b"), { wrapper }); + + await waitFor(() => expect(result.current.isSuccess).toBe(true)); + expect(result.current.data).toMatchObject({ user_id: "a b", user_alias: "Right User" }); + expect(userListCall).toHaveBeenCalledWith("test-access-token", ["a b"], 1, 100); + }); + it("falls back to the exact user list match when the user info endpoint returns a 404", async () => { const response = buildUserListResponse(1, 1); const exactUser = { ...response.users[1], user_id: "bob", user_alias: "Bob" }; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/hooks/users/useUsers.ts b/ui/litellm-dashboard/src/app/(dashboard)/hooks/users/useUsers.ts index 86e1276fee4..91699283835 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/hooks/users/useUsers.ts +++ b/ui/litellm-dashboard/src/app/(dashboard)/hooks/users/useUsers.ts @@ -91,14 +91,13 @@ export const useUserLookup = (userId: string | null) => { queryKey: userLookupKeys.detail(userId ?? ""), queryFn: async () => { try { - return mapUserInfoV2ToUserInfo(await userGetInfoV2(accessToken!, userId!)); + const user = await userGetInfoV2(accessToken!, userId!); + if (user.user_id === userId) return mapUserInfoV2ToUserInfo(user); } catch (error) { - if (error instanceof ApiError && error.status === 404) { - const response = await userListCall(accessToken!, [userId!], 1, USER_LIST_MAX_PAGE_SIZE); - return response.users.find((user) => user.user_id === userId) ?? null; - } - throw error; + if (!(error instanceof ApiError && error.status === 404)) throw error; } + const response = await userListCall(accessToken!, [userId!], 1, USER_LIST_MAX_PAGE_SIZE); + return response.users.find((user) => user.user_id === userId) ?? null; }, enabled: Boolean(accessToken) && Boolean(userId) && canListUsers(userRole), });