From 3ebe6800e054578599385ae5c5a7b85a2f07ed7a Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 23 Nov 2025 14:55:34 +0000 Subject: [PATCH] fix: prevent crash when navigating between metrics with different scenarios When navigating from one metric to another, the scenario state (e.g., "refusal" from completions) could persist briefly while the new metric's data was already loaded. If the new metric had different scenario keys (e.g., "explosion" from kl), accessing the stale key would crash. Changes: - Add early return if visualizations data is missing - Validate scenario key exists before accessing data - Fallback to first available scenario if current scenario is stale --- src/components/MetricVisualizer.jsx | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/components/MetricVisualizer.jsx b/src/components/MetricVisualizer.jsx index 46c6be6..9e80ce6 100644 --- a/src/components/MetricVisualizer.jsx +++ b/src/components/MetricVisualizer.jsx @@ -24,6 +24,11 @@ const MetricVisualizer = ({ metric }) => { const [healthyScenario, setHealthyScenario] = useState(null); const [unhealthyScenario, setUnhealthyScenario] = useState(null); + // Early return if visualizations data is missing or malformed + if (!metric?.visualizations) { + return null; + } + // Determine if data has multiple scenarios const healthyData = metric.visualizations.healthy; const unhealthyData = metric.visualizations.unhealthy; @@ -44,22 +49,32 @@ const MetricVisualizer = ({ metric }) => { } }, [metric, hasMultipleHealthy, hasMultipleUnhealthy]); - // Get current display data + // Get current display data with defensive checks for stale scenario state let currentData, currentAnalysis; if (mode === 'healthy') { - if (hasMultipleHealthy && healthyScenario) { + if (hasMultipleHealthy && healthyScenario && healthyData[healthyScenario]) { currentData = healthyData[healthyScenario].data; currentAnalysis = healthyData[healthyScenario].analysis; - } else { + } else if (hasMultipleHealthy) { + // Fallback to first scenario if current scenario is stale + const firstKey = Object.keys(healthyData)[0]; + currentData = healthyData[firstKey]?.data; + currentAnalysis = healthyData[firstKey]?.analysis; + } else if (healthyData) { currentData = healthyData.data; currentAnalysis = healthyData.analysis; } } else { - if (hasMultipleUnhealthy && unhealthyScenario) { + if (hasMultipleUnhealthy && unhealthyScenario && unhealthyData[unhealthyScenario]) { currentData = unhealthyData[unhealthyScenario].data; currentAnalysis = unhealthyData[unhealthyScenario].analysis; - } else { + } else if (hasMultipleUnhealthy) { + // Fallback to first scenario if current scenario is stale + const firstKey = Object.keys(unhealthyData)[0]; + currentData = unhealthyData[firstKey]?.data; + currentAnalysis = unhealthyData[firstKey]?.analysis; + } else if (unhealthyData) { currentData = unhealthyData.data; currentAnalysis = unhealthyData.analysis; }