Skip to content

fix(release-bubbles): guard handleMouseOut against ECharts state transition crash#119481

Closed
billyvg wants to merge 1 commit into
masterfrom
claude/serene-cannon-oppyfv
Closed

fix(release-bubbles): guard handleMouseOut against ECharts state transition crash#119481
billyvg wants to merge 1 commit into
masterfrom
claude/serene-cannon-oppyfv

Conversation

@billyvg

@billyvg billyvg commented Jul 13, 2026

Copy link
Copy Markdown
Member

Problem

Sentry issue: JAVASCRIPT-3AP8 — escalating, 296 events, 196 users affected.

Users hovering over release bubbles in the Explore → Releases view encounter an unhandled crash:

TypeError: Cannot read properties of undefined (reading 'get')

The crash originates deep in ECharts (MarkerModel._mergeOption → ecModel.eachSeries → seriesModel.get) and bubbles up through our handleMouseOut handler at useReleaseBubbles.tsx:552.

Root Cause

handleMouseOut calls echartsInstance.setOption({series: [{id: BUBBLE_AREA_SERIES_ID, markArea: {data: []}}]}, {lazyUpdate: true}) to clear the highlighted mark area when the mouse leaves a bubble.

During this merge, ECharts iterates all series models and applies marker options. If a concurrent lazyUpdate from handleMouseOver is still being processed, the chart's internal series model list can contain undefined entries, causing the crash.

The stack trace confirms the path:

handleMouseOut (useReleaseBubbles.tsx:552)
  → echartsInstance.setOption
  → GlobalModel._mergeOption
  → MarkerModel.mergeOption
  → ecModel.eachSeries
  → seriesModel.get(this.mainType, true)  ← crashes: seriesModel is undefined

Fix

  1. Add an isDisposed() guard before calling setOption, to handle the case where the chart instance has been torn down.
  2. Wrap the setOption call in a try/catch to swallow transient state transition errors. If the clear fails, the mark area will be cleaned up on the next mouse interaction.

Evidence

  • Issue escalating since 2026-07-06, 196 unique users impacted
  • Seer analysis: "Wrap setOption calls in mouse handlers with a try/catch and add an isDisposed guard to prevent crashes during chart state transitions"
  • Session replays confirm reproducibility on mousemove across the releases chart

Session

Claude session: https://claude.ai/code/session_014Ti4xAam9aMA4vPse1BLQu


Generated by Claude Code

…tions

ECharts crashes internally when `setOption` with `markArea: {data: []}` is called
during a chart state transition — e.g. while a concurrent lazyUpdate from
`handleMouseOver` is still being applied. The crash manifests as:
  TypeError: Cannot read properties of undefined (reading 'get')
in `MarkerModel._mergeOption` when iterating series models.

Add an `isDisposed()` guard and wrap the `setOption` call in a try/catch
so transient chart state errors don't surface as user-visible crashes.

Fixes JAVASCRIPT-3AP8

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Ti4xAam9aMA4vPse1BLQu
@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Jul 13, 2026
@billyvg billyvg closed this Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants