From 1b25f853ceed33c6600edc2b1a2ca7f07bb385d4 Mon Sep 17 00:00:00 2001 From: ryan-crabbe-berri Date: Tue, 5 May 2026 15:40:44 -0700 Subject: [PATCH] [Fix] Team UI: handle legacy dict shape for metadata.guardrails (#27224) * [Fix] Team UI: handle legacy dict shape for metadata.guardrails A team can have metadata.guardrails stored as {"modify_guardrails": bool} (the permission-flag shape introduced in PR #4810) rather than the expected string[]. The opt-out logic added in PR #25575 calls .filter() on this field, which throws TypeError on a dict and crashes the team detail page. Add a safeGuardrailsList helper that returns [] when the field is not an array, and route the three read sites through it. * [Fix] Team UI: inline Array.isArray guards for guardrails metadata Replace the safeGuardrailsList helper with inline Array.isArray checks at each call site, and apply the same guard to opted_out_global_guardrails for consistency. No known legacy dict rows for opted_out_global_guardrails, but the unguarded `|| []` pattern is the same shape risk. Six call sites now defended directly: three for metadata.guardrails and three for metadata.opted_out_global_guardrails. --- .../src/components/team/TeamInfo.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ui/litellm-dashboard/src/components/team/TeamInfo.tsx b/ui/litellm-dashboard/src/components/team/TeamInfo.tsx index d2c00e5326..8f3553a839 100644 --- a/ui/litellm-dashboard/src/components/team/TeamInfo.tsx +++ b/ui/litellm-dashboard/src/components/team/TeamInfo.tsx @@ -653,10 +653,12 @@ const TeamInfoView: React.FC = ({ const { team_info: info } = teamData; const initialKillSwitchOn = info.metadata?.disable_global_guardrails === true; - const optedOutGlobals = new Set(info.metadata?.opted_out_global_guardrails || []); - const nonGlobalOptIns: string[] = (info.metadata?.guardrails || []).filter( - (n: string) => !globalGuardrailNames.has(n), + const optedOutGlobals = new Set( + Array.isArray(info.metadata?.opted_out_global_guardrails) ? info.metadata.opted_out_global_guardrails : [], ); + const nonGlobalOptIns: string[] = ( + Array.isArray(info.metadata?.guardrails) ? info.metadata.guardrails : [] + ).filter((n: string) => !globalGuardrailNames.has(n)); const effectiveGuardrails: string[] = initialKillSwitchOn ? nonGlobalOptIns : [ @@ -815,8 +817,8 @@ const TeamInfoView: React.FC = ({ @@ -1619,8 +1621,8 @@ const TeamInfoView: React.FC = ({