agentleFS
adobeadobe/react-spectrum-charts/.agents/skills/fixing-bugs/SKILL.md

fixing-bugs

Skill131 starsChanged 8 days agoApache-2.0View on GitHub

Diagnoses and fixes react-spectrum-charts bugs, mapping symptoms (flicker, stuck hover, wrong popover, colors, S1/S2 parity) to the relevant architecture doc, then adds regression tests and stories. Use when fixing unexpected or broken behavior.

3 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

8 rules. 0 are common, 3 are distinctive, and 5 are very specific to this project.

  • 0

    Common

    Most of the 3 edited versions we read keep these.

  • 3

    Distinctive

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use this skill when fixing a bug.

    line 8
  2. Very specific:

    If this bug has a GitHub issue (gh issue view <number> --repo adobe/react-spectrum-charts), read it and start from its symptom, root cause, …

    line 14
  3. Distinctive:

    Treat the root cause as a starting hypothesis, not gospel.

    line 19
  4. Very specific:

    Before view.signal(name, value), check specSignalNames.has(name).

    line 61
  5. Very specific:

    Every signal write must have a corresponding clear.

    line 64
  6. Distinctive:

    Every bug fix must include a test that would have caught the bug:

    line 88
  7. Very specific:

    For encoding bugs: Test the spec builder function directly with toHaveProperty('key', value).

    line 94
  8. Very specific:

    For data bugs: Test addData directly with initializeSpec() and assert the transform array.

    line 96

“Common” is measured: kept by at least 6 in 10 of the 3 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

react-spectrum-charts: Bug Fix

Use this skill when fixing a bug. Use the table in Step 1 below to find which additional architecture file matches your bug's symptom.


Step 0: Check for a Linked Issue

If this bug has a GitHub issue (gh issue view <number> --repo adobe/react-spectrum-charts), read it and start from its symptom, root cause, cross-cutting checklist, and implementation plan instead of rediscovering them. Also search closed issues for the same symptom: this may be a regression of an earlier fix.

Treat the root cause as a starting hypothesis, not gospel. Re-verify it against the current code, since other changes may have landed since it was filed; re-locate files by symbol name if line numbers have drifted. If your understanding changes, update the issue body so it stays accurate. If no issue exists, proceed as below.

The PR description says Fixes #<number> so merging closes the issue.


Diagnosing a Bug

Step 1: Identify which layer the bug lives in

SymptomLayerWhere to lookArchitecture file
Chart flickers or disappears on resizeRender cycleVegaChart.tsx dep arrays, useSpec.tsx memo depsarchitecture/rendering-and-signals.md
Chart redraws when popover opens/closesRender cycleState mutations causing spec rebuildarchitecture/rendering-and-signals.md
Hover/selection stays stuck after interactionSignalclearHoverSignals, setSelectedSignals, useNewChartView.tsxarchitecture/rendering-and-signals.md
Popover opens with wrong content or for wrong markCOMPONENT_NAMEmarkClickUtils.ts, getTooltip() in mark utilsarchitecture/rendering-and-signals.md
Mark has wrong color that doesn't respect backgroundColorEncodingCheck for hardcoded color vs { signal: BACKGROUND_COLOR }architecture/encoding-and-props.md
Mouse events not firingInteraction wiringuseNewChartView.tsx, isInteractive(), voronoi mark existencearchitecture/mark-internals.md
TypeScript errors after tests passType systemRun yarn tsc --noEmit — Jest doesn't type-check—
Feature works in S1 but not S2S2 parityFind the S2 equivalent file and apply the same fixarchitecture/s2-parity.md

Step 2: Follow the data flow from symptom to root cause

For rendering bugs, trace backwards from the symptom:

  • "Chart re-embeds on resize" → find the dep that triggers the embed effect → trace where that dep comes from
  • "Chart blank on load" → check whether dimensions start at 0, check the hasMounted / needsInitEmbed pattern

For signal bugs, find the signal by name in the spec (spec.signals[]), then find every view.signal(name, ...) call — both the places that set it and the places that should clear it. A "stuck" signal almost always has a clear path that doesn't run in some interaction sequence.

For interaction bugs (click, right-click, legend), trace through useNewChartView.tsx which is where all Vega event listeners are registered. The click and contextmenu paths must receive the same arguments.


Key Rules (Not Past Incidents — These Are Principles)

Background colors use signals, not static values

Any fill/stroke that should track the chart's backgroundColor prop must use { signal: BACKGROUND_COLOR }. A static color value (getS2ColorValue(...) or { value: '#fff' }) is baked into the spec and will not react to runtime prop changes. This applies to halos, labels, and any "background-matching" visual element.

Signal writes need existence checks

Before view.signal(name, value), check specSignalNames.has(name). The set of signals in a spec varies based on which marks and features are active. Writing to an absent signal throws.

Signal clearing must be symmetric

Every signal write must have a corresponding clear. If you add signal state in a mouseenter handler, clear it in mouseleave. If you set selectedData on mark click, clear it on popover close. "Stuck" UI state is almost always an asymmetric signal write.

The resize and embed effects must stay separate

Width and height must not appear in the embed effect's dep array. Chart size changes must flow through the resize effect only. The spec should be rebuilt only when data, options, or config change — not when the container resizes.

Text marks hide via fontSize: 0, not fillOpacity: 0

Hiding a text mark with opacity still runs layout calculations (like limit constraints), which can produce NaN. Setting fontSize: 0 disables both rendering and layout.

Decorative/overlay marks need interactive: false

Any mark that is purely visual (annotation text, halo, badge, reference label) must have interactive: false. Without it, the mark intercepts mouse events meant for the data marks underneath it.

Use displayName for component identity, never reference equality

child.type === Component fails across hot-reload boundaries. Always use getElementDisplayName(child) === Component.displayName.

S2 parity is always required

When fixing a bug in an s1 file, find the corresponding s2 file (packages/vega-spec-builder-s2/ mirrors packages/vega-spec-builder/). Apply the same fix unless the bug doesn't exist in s2 — but verify, don't assume. S2 has intentional simplifications (no Venn, simpler static point rendering) so don't port s1-specific behavior blindly.

Comments stay short — no narration of the fix

New or touched functions get at most a one-line JSDoc (description + @param/@returns), matching the length of sibling functions in the same file. Do not add paragraphs explaining what bug was fixed, why, or what the investigation found — that belongs in the PR description and commit message, never in the code. See AGENTS.md's Code Style section for a worked example.


Writing the Regression Test

Every bug fix must include a test that would have caught the bug:

For render bugs: Assert DOM node identity is preserved after the interaction that triggered the bug. node.isConnected === true after a popover opens and closes means the node was not recreated.

For signal bugs: Exercise the full cycle (set → interact → clear) in a single test. Assert that the visual state is correct after the closing interaction, not just after the opening one.

For encoding bugs: Test the spec builder function directly with toHaveProperty('key', value). Do not use direct property access on Vega encode objects — Vega uses ProductionRule<T> union types, and TypeScript will reject direct access.

For data bugs: Test addData directly with initializeSpec() and assert the transform array. Prefer unit tests on spec builder functions over integration tests for data pipeline issues.

For visual bugs in S2: If no variation in the chart's dashboard would show the bug, add or adjust one (see AGENTS.md's "Variation Dashboards"); the Regressions story still covers the exact reproduction. If the fix changes documented behavior, update the component's packages/docs-s2 page.

Once the fix is complete, run yarn verify before pushing (see AGENTS.md's Test Completeness Checklist) — test passes do not imply type correctness. Don't run it proactively after every change.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.