Skip to content

fix(ui): invalidate org queries after team mutations#25812

Merged
ryan-crabbe-berri merged 4 commits intolitellm_internal_stagingfrom
litellm_fix-invalidate-orgs-on-team-mutation
Apr 16, 2026
Merged

fix(ui): invalidate org queries after team mutations#25812
ryan-crabbe-berri merged 4 commits intolitellm_internal_stagingfrom
litellm_fix-invalidate-orgs-on-team-mutation

Conversation

@ryan-crabbe-berri
Copy link
Copy Markdown
Collaborator

@ryan-crabbe-berri ryan-crabbe-berri commented Apr 15, 2026

Summary

The organization info page didn't reflect team↔org membership changes until a hard reload. Two coordinated fixes:

  1. Invalidate the organization React Query cache after team mutations (teamCreateCall, teamDeleteCall, teamUpdateCall) in TeamsView, CreateTeamModal, and TeamInfo. Pattern matches hooks/projects / hooks/budgets / hooks/accessGroupsorganizationKeys.all so list and detail queries both invalidate. Requires exporting organizationKeys from useOrganizations.ts.
  2. Migrate organization_view.tsx to the existing useOrganization(id) hook, dropping local orgData/loading state, the fetchOrgInfo function, and its useEffect. Each of the 4 post-mutation fetchOrgInfo() calls becomes queryClient.invalidateQueries({ queryKey: organizationKeys.all }). Without this migration, step 1 had no visible effect on the org info page since it was reading from a separate manually-managed copy of the data. Net: −26 / +9 lines.

Out of scope (follow-up): the Teams page Organization column staleness — useFetchTeams doesn't use React Query at all, which is a larger refactor.

Screenshots

Before

Edit a team's organization elsewhere → return to old org's info page → moved team still appears in the Teams badge list until Cmd+R.

image

After

Same flow → moved team disappears from the source org and appears in the destination org without a reload.

Screenshot 2026-04-15 at 1 23 01 PM Screenshot 2026-04-15 at 1 23 47 PM Screenshot 2026-04-15 at 1 24 03 PM

Test plan

Pre-req: 2 organizations and 1 team assigned to one of them.

  • The fix: Organizations → Org X (note team badge) → Teams → edit that team → change Organization to Org Y → Save → Organizations → Org X again. Badge is gone. Org Y now shows it. No Cmd+R needed.
  • Org info page didn't regress from the migration: open Org X → Edit Organization → change alias → Save. Title updates immediately.
  • Org members didn't regress: Members tab → add a member → row appears. Delete it → row disappears. Both without reload.
  • Loading state still works: hard reload directly on an org info URL → loading state shows briefly, then content.

Team create/delete/update can change which teams belong to an organization
(via teamCreateCall, teamDeleteCall, and teamUpdateCall when organization_id
changes). Without invalidating the React Query cache for organizations, the
org info page's teams list and any useOrganizations() consumer (e.g. the
team edit form's organization dropdown) stay stale until a hard reload.

Export organizationKeys from useOrganizations and invalidate
organizationKeys.all after each successful team mutation, matching the
pattern used in hooks/projects, hooks/budgets, and hooks/accessGroups.
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
litellm Ready Ready Preview, Comment Apr 16, 2026 5:43am

Request Review

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 15, 2026

Greptile Summary

Two coordinated changes fix stale org data after team mutations: organizationKeys is exported from useOrganizations.ts and queryClient.invalidateQueries is called after every team create, delete, and update. organization_view.tsx is also migrated from a manual fetch/useEffect pattern to the existing useOrganization(id) hook, so cache invalidations from the other files are actually reflected on the org info page. Tests are updated to mock the hook instead of the raw network call.

Confidence Score: 5/5

Safe to merge — changes are narrowly scoped cache invalidations and a clean hook migration with no logic changes.

All six files have straightforward, well-tested changes. No new logic is introduced: mutations now call invalidateQueries using an exported key factory, and organization_view migrates to an already-existing hook. Tests are correctly updated to mock the hook rather than the raw network call, and renderWithProviders supplies the required QueryClient context. No P0 or P1 findings.

No files require special attention.

Important Files Changed

Filename Overview
ui/litellm-dashboard/src/app/(dashboard)/hooks/organizations/useOrganizations.ts Adds export to organizationKeys so downstream consumers can reference the same key factory; no functional change to the hook logic.
ui/litellm-dashboard/src/components/organization/organization_view.tsx Replaces manual fetch/useEffect with useOrganization hook; each post-mutation fetchOrgInfo call becomes queryClient.invalidateQueries. Clean reduction in code with no behavioral regression.
ui/litellm-dashboard/src/components/organization/organization_view.test.tsx Tests correctly updated to mock useOrganization instead of organizationInfoCall; switches to renderWithProviders for proper QueryClient context; no coverage regression.
ui/litellm-dashboard/src/app/(dashboard)/teams/TeamsView.tsx Adds org cache invalidation after teamDeleteCall; straightforward and consistent with the established pattern.
ui/litellm-dashboard/src/app/(dashboard)/teams/components/modals/CreateTeamModal.tsx Adds org cache invalidation after teamCreateCall; straightforward.
ui/litellm-dashboard/src/components/team/TeamInfo.tsx Adds org cache invalidation after teamUpdateCall; consistent with the pattern added in the other team files.

Sequence Diagram

sequenceDiagram
    participant User
    participant Component as TeamsView / CreateTeamModal / TeamInfo / OrgView
    participant API
    participant QC as QueryClient
    participant useOrg as useOrganization(id)

    User->>Component: Mutate (create/update/delete team or org member)
    Component->>API: teamCreateCall / teamDeleteCall / teamUpdateCall / org member call
    API-->>Component: Success response
    Component->>QC: invalidateQueries(organizationKeys.all)
    QC->>useOrg: Mark detail query stale → refetch
    QC->>QC: Mark list query stale → refetch
    useOrg->>API: GET /organization/{id}
    API-->>useOrg: Fresh org data
    useOrg-->>Component: Re-render org info page with updated teams/members
Loading

Reviews (4): Last reviewed commit: "Merge remote-tracking branch 'origin/lit..." | Re-trigger Greptile

Replace the local orgData/loading useState + fetchOrgInfo useEffect in
OrganizationInfoView with the existing useOrganization(id) React Query
hook, and replace each post-mutation fetchOrgInfo() call with
queryClient.invalidateQueries({ queryKey: organizationKeys.all }).

This makes the org info page benefit from the React Query cache
invalidation already added for team mutations: editing a team's
organization elsewhere now refreshes the org's Teams badge list (and
all other org-derived data) without a hard reload.
Replace the organizationInfoCall mock with a vi.mock of the
useOrganizations hook module that stubs useOrganization (and
organizationKeys, which the component still imports for invalidation).
Each test now sets mockUseOrganization.mockReturnValue(...) instead of
mocking the underlying network call, matching the existing pattern in
TeamInfo.test.tsx.

Renders go through the canonical renderWithProviders helper from
tests/test-utils so the component's useQueryClient() call has a
QueryClientProvider in context. This is the standard wrapper used by
~96 other test files in the dashboard.

Fixes "No QueryClient set" failures in the 4 organization_view tests
introduced by the imperative-fetch -> useOrganization migration.
@ryan-crabbe-berri ryan-crabbe-berri changed the base branch from litellm_internal_staging to main April 15, 2026 22:30
@ryan-crabbe-berri ryan-crabbe-berri changed the base branch from main to litellm_internal_staging April 15, 2026 22:53
@ryan-crabbe-berri ryan-crabbe-berri merged commit ed0138b into litellm_internal_staging Apr 16, 2026
89 of 97 checks passed
@ryan-crabbe-berri ryan-crabbe-berri deleted the litellm_fix-invalidate-orgs-on-team-mutation branch April 16, 2026 05:51
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.

2 participants