Skip to content

fix: isolate logs team filter dropdown from root teams state bleed#25716

Merged
ryan-crabbe-berri merged 1 commit intomainfrom
litellm_fix-logs-team-filter-state-bleed
Apr 14, 2026
Merged

fix: isolate logs team filter dropdown from root teams state bleed#25716
ryan-crabbe-berri merged 1 commit intomainfrom
litellm_fix-logs-team-filter-state-bleed

Conversation

@ryan-crabbe-berri
Copy link
Copy Markdown
Collaborator

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

Summary

  • The Logs view's Team ID filter dropdown was reading allTeams from the root teams state in app/page.tsx, which OldTeams overwrites with the filtered subset whenever a user searches on the Teams page. Applying a team search on the Teams page made filtered-out teams disappear from the Logs filter dropdown in a separate part of the app.
  • Swap the Team ID filter to use the existing TeamDropdown component via a small FilterTeamDropdown wrapper that adapts it to the filter slot's FilterOptionCustomComponentProps contract. The dropdown now drives its own useInfiniteTeams query against /v2/team/list with server-side team_alias search and an isolated react-query cache, unreachable from root state.
  • Rename the now-unused hookAllTeams destructure in SpendLogsTable to allTeams so the KeyInfoView passthrough receives the hook's unpolluted fetch instead of the polluted prop, and drop the dead allTeams prop from SpendLogsTable and both of its call sites (app/page.tsx, app/(dashboard)/logs/page.tsx).

screenshots

before
Screenshot 2026-04-14 at 1 44 47 PM
Screenshot 2026-04-14 at 1 44 57 PM

after
Screenshot 2026-04-14 at 2 27 19 PM
Screenshot 2026-04-14 at 2 27 34 PM

Test plan

  • Seed 5 bleed-* teams via /team/new, fire one request through the proxy to produce a log entry
  • Baseline: Observability → Logs → open Team ID filter → type bleed → all 5 teams appear
  • Trigger: Access Control → Teams → search bleed-acme → table narrows to one row (root teams state now polluted)
  • Fix verified: Observability → Logs → open Team ID filter → type bleed → all 5 teams still appear (dropdown reads from its own useInfiniteTeams cache, not root state)
  • Select a team in the filter, click Apply Filters → logs table narrows to that team
  • Click Reset Filters → dropdown clears, logs table returns to unfiltered
  • Click a log row → KeyInfoView panel opens and renders correctly (now receives the hook's unpolluted allTeams)
  • npx vitest run src/components/view_logs/index.test.tsx src/components/view_logs/log_filter_logic.test.tsx → 38/38 passing
  • tsc --noEmit → zero new errors on touched files

The Logs view's Team ID filter dropdown was reading `allTeams` from the
root `teams` state in page.tsx, which the Teams page search overwrites
with its filtered subset. Applying a team search on the Teams page made
filtered-out teams disappear from the Logs filter dropdown.

Swap the Team ID filter to use the existing `TeamDropdown` component via
a small `FilterTeamDropdown` wrapper that adapts it to the filter slot's
`FilterOptionCustomComponentProps` contract. The dropdown now drives its
own `useInfiniteTeams` query against `/v2/team/list` with server-side
search and an isolated react-query cache, unreachable from root state.

Rename the now-unused `hookAllTeams` destructure to `allTeams` so the
`KeyInfoView` passthrough receives the hook's unpolluted fetch instead
of the polluted prop, and drop the dead `allTeams` prop from
`SpendLogsTable` and both of its call sites.
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 14, 2026

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

Project Deployment Actions Updated (UTC)
litellm Ready Ready Preview, Comment Apr 14, 2026 9:30pm

Request Review

@codspeed-hq
Copy link
Copy Markdown
Contributor

codspeed-hq bot commented Apr 14, 2026

Merging this PR will not alter performance

✅ 16 untouched benchmarks


Comparing litellm_fix-logs-team-filter-state-bleed (1beb803) with main (0e43050)

Open in CodSpeed

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 14, 2026

Greptile Summary

This PR fixes a state bleed bug where searching on the Teams page would overwrite the shared teams root state, causing the Logs view's Team ID filter dropdown to show only the filtered subset. The fix replaces the inline client-side search (over the polluted prop) with a new FilterTeamDropdown wrapper that delegates to TeamDropdown, which drives its own isolated useInfiniteTeams / react-query cache against /v2/team/list. The allTeams prop is removed from SpendLogsTable entirely; KeyInfoView now receives the unpolluted data via the existing useLogFilterLogic hook return value.

Confidence Score: 5/5

Safe to merge — the fix is well-scoped, all 38 tests pass, and the only remaining note is a P2 UX inconsistency about the ignored placeholder.

All findings are P2 (style/UX). The core state-isolation fix is correct, test coverage is maintained, and no regressions are introduced.

No files require special attention.

Important Files Changed

Filename Overview
ui/litellm-dashboard/src/components/common_components/FilterTeamDropdown.tsx New 10-line wrapper bridging TeamDropdown to FilterOptionCustomComponentProps; placeholder prop is ignored (intentional, minor UX inconsistency)
ui/litellm-dashboard/src/components/view_logs/index.tsx Removes allTeams prop, replaces inline client-side search with FilterTeamDropdown customComponent, and renames hookAllTeams→allTeams for KeyInfoView passthrough
ui/litellm-dashboard/src/app/page.tsx Removes allTeams prop from SpendLogsTable call site; no other changes
ui/litellm-dashboard/src/app/(dashboard)/logs/page.tsx Drops useTeams hook and allTeams prop entirely from the Logs page; clean removal
ui/litellm-dashboard/src/components/view_logs/index.test.tsx Removes Team import and allTeams from defaultProps to match removed prop; mock for useLogFilterLogic still correctly includes allTeams

Sequence Diagram

sequenceDiagram
    participant TeamsPage as Teams Page (OldTeams)
    participant RootState as Root teams state (app/page.tsx)
    participant LogsFilter as Logs Team ID Filter
    participant FilterTeamDD as FilterTeamDropdown
    participant TeamDD as TeamDropdown
    participant InfiniteTeams as useInfiniteTeams (/v2/team/list)

    Note over TeamsPage,LogsFilter: BEFORE (buggy)
    TeamsPage->>RootState: search "bleed-acme" → overwrites teams[]
    LogsFilter->>RootState: read allTeams prop → sees only filtered subset ❌

    Note over FilterTeamDD,InfiniteTeams: AFTER (fixed)
    TeamsPage->>RootState: search "bleed-acme" → overwrites teams[]
    LogsFilter->>FilterTeamDD: render customComponent with value/onChange
    FilterTeamDD->>TeamDD: delegate value & onChange
    TeamDD->>InfiniteTeams: own isolated react-query cache
    InfiniteTeams-->>TeamDD: full unfiltered teams list ✅
    TeamDD-->>LogsFilter: shows all teams regardless of root state
Loading

Reviews (1): Last reviewed commit: "fix: isolate logs team filter dropdown f..." | Re-trigger Greptile

Comment on lines +5 to +8
const FilterTeamDropdown: React.FC<FilterOptionCustomComponentProps> = ({
value,
onChange,
}) => <TeamDropdown value={value} onChange={onChange} />;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Placeholder prop silently dropped

FilterOptionCustomComponentProps includes an optional placeholder prop, and filter.tsx always passes "Select Team ID..." to every customComponent. FilterTeamDropdown receives it but never forwards it, so users will always see TeamDropdown's hardcoded "Search or select a team" instead. This is a minor UX inconsistency vs every other filter slot. If intentional, a comment noting the deviation is worth adding; if not, TeamDropdown can accept an optional placeholder prop.

Suggested change
const FilterTeamDropdown: React.FC<FilterOptionCustomComponentProps> = ({
value,
onChange,
}) => <TeamDropdown value={value} onChange={onChange} />;
const FilterTeamDropdown: React.FC<FilterOptionCustomComponentProps> = ({
value,
onChange,
// placeholder is intentionally ignored — TeamDropdown has its own label
}) => <TeamDropdown value={value} onChange={onChange} />;

@yuneng-berri yuneng-berri self-requested a review April 14, 2026 21:41
@ryan-crabbe-berri ryan-crabbe-berri merged commit 43efe76 into main Apr 14, 2026
97 of 106 checks passed
@ryan-crabbe-berri ryan-crabbe-berri deleted the litellm_fix-logs-team-filter-state-bleed branch April 14, 2026 21:44
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