Skip to content

fix(ui): wire team_id filter to key alias dropdown on Virtual Keys tab - #25114

Merged
ryan-crabbe-berri merged 1 commit into
litellm_ryan-march-31from
litellm_fix-virtual-keys-team-filter-alias-dropdown
Apr 3, 2026
Merged

fix(ui): wire team_id filter to key alias dropdown on Virtual Keys tab#25114
ryan-crabbe-berri merged 1 commit into
litellm_ryan-march-31from
litellm_fix-virtual-keys-team-filter-alias-dropdown

Conversation

@ryan-crabbe-berri

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

Copy link
Copy Markdown
Contributor

Summary

  • The Key Alias dropdown on the Virtual Keys page was showing aliases from all teams regardless of which team was selected — team_id was never passed through the frontend to the /key/aliases backend endpoint
  • Added team_id as an optional query parameter to the backend /key/aliases endpoint
  • Wired team_id through the full frontend chain: keyAliasesCalluseInfiniteKeyAliasesPaginatedKeyAliasSelect
  • Extended the FilterComponent framework to pass current filter state (allFilters) to custom filter components so they can react to sibling filter values

Screenshots

Screenshot 2026-04-03 at 3 37 02 PM Screenshot 2026-04-03 at 3 37 17 PM Screenshot 2026-04-03 at 3 37 30 PM

Test plan

  • No team selected → Key Alias dropdown shows all aliases
  • Select team-alpha → Key Alias dropdown shows only alpha-* aliases
  • Select team-beta → Key Alias dropdown shows only beta-* aliases
  • Select a team + select an alias → key table shows matching result (not 0)
  • Clear team filter → alias dropdown returns to showing all aliases
  • Verify /key/aliases?team_id=<id> returns only that team's aliases via curl

The Key Alias dropdown on the Virtual Keys page was showing aliases from
all teams regardless of which team was selected. The team_id was never
passed through the frontend chain to the backend /key/aliases endpoint.

- Backend: add optional team_id query param to /key/aliases endpoint
- networking.tsx: add team_id param to keyAliasesCall
- useKeyAliases: accept and forward team_id to API call and query key
- filter.tsx: pass allFilters context to custom filter components
- PaginatedKeyAliasSelect: read Team ID from allFilters and pass to hook
@vercel

vercel Bot commented Apr 3, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
litellm Ready Ready Preview, Comment Apr 3, 2026 10:45pm

Request Review

@greptile-apps

greptile-apps Bot commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR wires team_id through the full filter chain — backend /key/aliases endpoint → keyAliasesCalluseInfiniteKeyAliases hook → PaginatedKeyAliasSelect — so the Key Alias dropdown on the Virtual Keys tab only shows aliases belonging to the currently-selected team, and extends the FilterComponent framework to pass sibling filter state (allFilters) to custom filter components.

Key changes:

  • Backend /key/aliases accepts a new optional team_id query param, correctly appended as a parameterized SQL condition after the existing non-admin scope filter
  • React Query cache key includes team_id, so switching teams invalidates the previous team's alias cache and fetches fresh data
  • FilterComponent now passes tempValues as allFilters to all custom components, enabling them to react to sibling filter values
  • The filter.tsx change has a beneficial undocumented side effect: the Key Alias dropdown in the view_logs page will also now be scoped by team when a Team ID filter is active there

Notable findings:

  • When the Team ID filter changes, the previously selected Key Alias is not cleared; combining the new team with the stale alias immediately returns 0 results and can confuse users
  • PaginatedKeyAliasSelect couples itself to the string "Team ID" with no type-level enforcement; an explicit teamId prop would be safer
  • A debug console.log of the full API response is left in the keyAliasesCall production path
  • The inline from litellm.proxy.proxy_server import prisma_client import inside the endpoint function body is flagged by the project style guide

Confidence Score: 5/5

Safe to merge; all findings are non-blocking style and UX suggestions with no correctness, security, or data-integrity impact.

The core change — parameterizing /key/aliases with team_id and threading it through the frontend — is logically correct, properly parameterized (no SQL injection risk), and cache-keyed correctly so stale data is never served. All remaining findings are P2: a stale-selection UX edge case, a fragile string-key coupling, a leftover console.log, and a style-guide note on an inline import. None affect correctness or data integrity.

filter.tsx (stale sibling-filter clearing) and PaginatedKeyAliasSelect.tsx (hardcoded filter key lookup)

Important Files Changed

Filename Overview
litellm/proxy/management_endpoints/key_management_endpoints.py Adds optional team_id query parameter to the /key/aliases endpoint; correctly appended to the parameterized raw-SQL WHERE clause consistent with the existing search param pattern.
ui/litellm-dashboard/src/components/networking.tsx Adds optional team_id param to keyAliasesCall; correctly conditionally appended to URLSearchParams. A pre-existing console.log of the full response remains in the production path.
ui/litellm-dashboard/src/app/(dashboard)/hooks/keys/useKeyAliases.ts Threads team_id through the React Query hook; correctly included in the queryKey so cache is keyed per team, ensuring stale data from the previous team is not served.
ui/litellm-dashboard/src/components/KeyAliasSelect/PaginatedKeyAliasSelect/PaginatedKeyAliasSelect.tsx Reads team_id from the allFilters bag via the hardcoded key "Team ID", an implicit contract on filter option naming; does not reset its selection when the team filter changes.
ui/litellm-dashboard/src/components/molecules/filter.tsx Passes tempValues as allFilters to custom filter components — a clean mechanism for sibling-filter awareness — but does not clear dependent sibling values when a parent filter changes, leading to stale selections.

Sequence Diagram

sequenceDiagram
    participant User
    participant FilterComponent
    participant PaginatedKeyAliasSelect
    participant useInfiniteKeyAliases
    participant keyAliasesCall
    participant Backend as /key/aliases

    User->>FilterComponent: Select Team ID
    FilterComponent->>FilterComponent: update tempValues["Team ID"]
    FilterComponent->>PaginatedKeyAliasSelect: re-render with allFilters
    PaginatedKeyAliasSelect->>useInfiniteKeyAliases: call with team_id
    useInfiniteKeyAliases->>keyAliasesCall: fetch page 1 + team_id
    keyAliasesCall->>Backend: GET /key/aliases?page=1&team_id=...
    Backend-->>keyAliasesCall: filtered aliases for team
    keyAliasesCall-->>PaginatedKeyAliasSelect: dropdown shows team aliases only

    User->>FilterComponent: Clear Team ID
    FilterComponent->>PaginatedKeyAliasSelect: re-render with allFilters (Team ID empty)
    PaginatedKeyAliasSelect->>useInfiniteKeyAliases: call with team_id=undefined
    useInfiniteKeyAliases->>keyAliasesCall: fetch page 1, no team_id
    keyAliasesCall->>Backend: GET /key/aliases?page=1
    Backend-->>keyAliasesCall: all aliases
    keyAliasesCall-->>PaginatedKeyAliasSelect: dropdown shows all aliases
Loading

Comments Outside Diff (3)

  1. litellm/proxy/management_endpoints/key_management_endpoints.py, line 4367-4369 (link)

    P2 Inline import inside function body

    from litellm.proxy.proxy_server import prisma_client is placed inside the function body rather than at module level. CLAUDE.md style guidance says to avoid imports within methods — they make dependencies harder to trace and hurt readability — with an exception only for unavoidable circular imports.

    If the circular-import exception applies here (which it may, given proxy_server.py imports this module), that should be documented with a comment explaining why the inline import is necessary, rather than left implicit.

    Context Used: CLAUDE.md (source)

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

  2. ui/litellm-dashboard/src/components/networking.tsx, line 3299 (link)

    P2 Debug console.log left in production path

    console.log("/key/aliases API Response:", data) will emit every API response to the browser console in production, potentially leaking key alias metadata to anyone with devtools open. This should be removed or downgraded to a conditional debug-level statement.

  3. ui/litellm-dashboard/src/components/molecules/filter.tsx, line 107-113 (link)

    P2 Stale sibling-filter value not cleared when a parent filter changes

    When a user selects a team, picks an alias from that team's aliases, then switches to a different team, tempValues["Team ID"] updates but tempValues["Key Alias"] retains the previously selected alias. onApplyFilters is immediately called with both values, so downstream consumers apply the new team filter combined with the stale alias from the old team, returning 0 results with no indication to the user.

    Consider clearing dependent sibling filters when a parent filter changes — for example, resetting "Key Alias" whenever "Team ID" changes. To keep the logic reusable, this dependency could be expressed as an optional clearSiblings field on FilterOption rather than hardcoded inside handleFilterChange.

Reviews (1): Last reviewed commit: "fix(ui): wire team_id filter to key alia..." | Re-trigger Greptile

wait: DEBOUNCE_MS,
});

const teamId = allFilters?.["Team ID"] || undefined;

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 Hardcoded filter key couples component to naming convention

allFilters?.["Team ID"] creates an implicit contract that any enclosing FilterComponent must have a filter option whose name is exactly "Team ID". This happens to hold for both VirtualKeysTable.tsx and view_logs/index.tsx today, but the component itself has no way to enforce or document this assumption. If any page renames the team filter or reuses PaginatedKeyAliasSelect outside of FilterComponent, the extracted teamId will silently resolve to undefined and team-scoping will be dropped without any error or warning.

A more explicit and type-safe approach is to expose teamId as a first-class optional prop alongside allFilters, falling back to allFilters only when the explicit prop is absent.

@ryan-crabbe-berri
ryan-crabbe-berri merged commit 1521004 into litellm_ryan-march-31 Apr 3, 2026
50 of 58 checks passed
@ryan-crabbe-berri
ryan-crabbe-berri deleted the litellm_fix-virtual-keys-team-filter-alias-dropdown branch April 3, 2026 23:06
fzowl pushed a commit to fzowl/litellm that referenced this pull request Jun 24, 2026
…s-team-filter-alias-dropdown

fix(ui): wire team_id filter to key alias dropdown on Virtual Keys tab
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.

1 participant