diagnosing-bugs
SkillMonitoring & opsGuides your agent through methodically diagnosing bugs, flaky tests, CI hangs, and crashes.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the diagnosing-bugs skill
About this capability
A discipline for hard bugs, flaky tests, CI hangs, native crashes, and performance regressions in this SDK. Use when the user says "diagnose" or "debug this", reports something broken/throwing/failing/hanging/slow/crashing, or a test is flaky. Builds a tight, red-capable feedback loop before hypothe
What this skill tells your AI
The instructions your AI receives, as published by getsentry/sentry-react-native in .agents/skills/diagnosing-bugs/SKILL.md and read by ahel’s review.
A discipline for hard bugs. Skip a phase only when you can say why.
The whole skill is Phase 1: get a loop that goes red on this bug. Everything after is mechanical once you have it. If you catch yourself reading code to form a theory before that loop exists, stop — jumping to a hypothesis without a red-capable loop is the exact failure this prevents.
For trivial bugs with an obvious fix and an obvious test, skip this and just write the failing test — this skill is for the bugs that resist.
Phase 1 — Build a feedback loop
A tight loop is fast, deterministic, and goes red on this bug. Build one and the bug is 90% solved. Be aggressive and creative here — spend disproportionate effort.
Ways to construct one — try roughly in this order
- Failing Jest test at the seam —
yarn test path/to/file.test.ts -t 'name', at whatever seam reaches the bug. Tightest loop there is. Mock the bridge viatest/mockWrapper.ts. - Fake-timer harness — for flush timers, debounces, retries, and most flakes:
jest.useFakeTimers()and advance the clock deterministically instead of waiting. - Arch/platform matrix — reproduce under the failing combination: pin
Platform.OS,isTurboModuleEnabled(),isFabricEnabled(). "Only on New Arch" or "only on Android" is a clue and the loop's config. - Replay a captured payload — save a real envelope / event / native payload to disk and push it through the code path in isolation. Great for serialization / round-trip bugs.
- Throwaway harness — a minimal script exercising the bug path with mocked deps.
- Sample app — when the bug only shows end-to-end, reproduce in
samples/react-native(orsamples/expo); see theirAGENTS.md. Slower loop; use only when a unit seam can't reach it. - Native repro — for a native crash / leak, reproduce in the native test targets (iOS
RNSentryCocoaTester, Android instrumentation) or with the sample app + native debugger. The bridge can't be faked here. - Stress / repetition loop — for non-deterministic bugs: run the trigger 100×, narrow timing windows, inject delays. Goal is a higher reproduction rate, not a clean repro.
- Differential loop — same input through two versions/configs (e.g. before/after a dependency or RN bump) and diff the output. For regressions that "appeared after X".
Tighten the loop
Once you have a loop, treat it as a product: faster (narrow scope, skip unrelated init), sharper (assert the exact symptom the user described, not "didn't crash"), more deterministic (fake timers, seed randomness, no real network/bridge). A 2-second deterministic loop beats a 30-second flaky one. For non-deterministic bugs the goal is a high enough reproduction rate to debug against — 50% is debuggable, 1% is not.
Completion criterion
Phase 1 is done when you can name one command — a test invocation or script — that you have already run at least once (paste the invocation and its output), and that is:
- Red-capable — drives the actual bug path and asserts the user's exact symptom
- Deterministic — same verdict every run (flaky bugs: a pinned, high reproduction rate)
- Fast — seconds, not minutes
No red-capable command, no Phase 2.
When you genuinely cannot build a loop
Say so explicitly, list what you tried, and ask the user for: an environment that reproduces it, a captured artifact (envelope dump, native crash log / symbolicated stack, CI run, screen recording with timestamps, adb logcat / Xcode console output), or permission for temporary instrumentation. Do not hypothesise without a loop.
Phase 2 — Reproduce and minimise
Run the loop, watch it go red. Confirm it produces the failure mode the user described — not a nearby one (wrong bug = wrong fix). Then shrink the repro to the smallest scenario that still goes red: cut inputs, callers, config, and steps one at a time, re-running after each cut. Done when every remaining element is load-bearing. The minimal repro becomes the regression test.
Phase 3 — Hypothesise
Generate 3–5 ranked, falsifiable hypotheses before testing any — a single hypothesis anchors you on the first plausible idea. Each states its prediction: "If X is the cause, then changing Y makes the bug vanish." If you can't state the prediction, it's a vibe — sharpen or discard it. Show the ranked list to the user; they often re-rank it instantly ("we just changed #3"). Common suspects in this SDK: arch/platform branch, bridge serialization, timer/async ordering, scope-sync recursion, native memory/lifecycle, RN or native-SDK version skew.
Phase 4 — Instrument & fix
Confirm the hypothesis with the cheapest observation that would falsify it (a log via debug, a native breakpoint, a diffed payload) before changing code. Then make the minimal fix, watch the loop go green, and keep the minimal repro as the regression test. Re-run the broader suite (yarn test) and, for native/bridge fixes, the affected native tests and both architectures.
Signals
- GitHub stars
- 2k
- Forks
- 367
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
diagnosing-bugs-getsentry- Source
- github.com/getsentry/sentry-react-native