debug-rn-native-crash
Skill627 starsChanged 8 days agoMITView on GitHub
Investigate native React Native crashes (Fabric/Hermes/iOS) in ledger-live-mobile when JS error logs are missing or unhelpful. Use when the app dies silently, throws an NSException on iOS, or shows only a native stack trace.
In this repository70 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .github/copilot-instructions.mdCopilot instructions
- analyticsSkill
- batch-feature-devSkill
- ci-runnersSkill
- ci-workflow-refsSkill
- cleanupSkill
- client-idsSkill
- cloud-sync-moduleSkill
- codeownershipSkill
- coin-families-contractSkill
- coin-modulesSkill
- commentsSkill
- configurationSkill
- console-logSkill
- create-changesetSkill
- create-prSkill
- data-layer-advancedSkill
- dependency-patchesSkill
- detect-data-leaksSkill
- device-intent-executorSkill
- devtools-import-boundarySkill
- dialogs-sliceSkill
- docs-migrateSkill
- docs-update-or-createSkill
- domain-dataSkill
- e2e-desktop-add-or-updateSkill
- e2e-desktop-onboardSkill
- e2e-earnSkill
- e2e-mobile-add-or-updateSkill
- e2e-mobile-onboardSkill
- e2e-swapSkill
- errorsSkill
- feature-devSkill
- fix-ciSkill
- flow-packageSkill
- get-pr-commentsSkill
- git-conventionsSkill
- i18n-keysSkill
- impacting-prsSkill
- knip-migrationSkill
- ldls-nativeSkill
- ldls-webSkill
- ledger-wallet-cliSkill
- legacy-migrationSkill
- mvvm-architectureSkill
- new-packageSkill
- package-public-apiSkill
- pnpm-resolutionSkill
- prefer-set-hasSkill
- pre-reviewSkill
- react-generalSkill
- rebuild-to-fix-lib-import-errorsSkill
- remove-feature-flagSkill
- run-buildsSkill
- run-e2e-ciSkill
- runner-imagesSkill
- run-testsSkill
- slack-pr-messageSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
7 rules. About 0 are common, 5 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 12
Only a native stack trace (RCTViewComponentView, RCTPerformMountInstructions, …) with no JS source
- Distinctive: line 16
If the JS console already gives a clear stack, don't use this skill — read the JS error.
- Distinctive: line 36
Stop the running app first (otherwise Xcode can't attach cleanly).
- Very specific: line 80
If the watcher is broken, restart Metro with --reset-cache.
- Distinctive: line 84
Don't guess at causes from the JS code alone — the native debugger is the source of truth.
- Distinctive: line 85
Don't trust "the bug only happens when flag X is on" until the user has tested both states.
- Distinctive: line 86
Don't apply five fixes at once.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Debug RN native crash
Trigger
The mobile app crashes with one of:
- A native iOS exception (
NSInternalInconsistencyException,RCTFatal, Fabric assertion) - Only a native stack trace (
RCTViewComponentView,RCTPerformMountInstructions, …) with no JS source - "Failed to symbolicate" in Metro and no actionable JS error
- Reproducible crash but unclear which RN component is at fault
If the JS console already gives a clear stack, don't use this skill — read the JS error.
Workflow
1. Capture the native exception from the simulator
xcrun simctl list devices booted # get the booted sim UDID
xcrun simctl spawn <UDID> log show --last 5m --style compact \
--predicate 'processImagePath CONTAINS "ledgerlivemobile" AND (eventMessage CONTAINS "Assertion failure" OR eventMessage CONTAINS "Attempt to unmount" OR eventMessage CONTAINS "Terminating app")'Extract the exception message, native stack, and any view descriptors (frame, tag, backgroundColor, alpha). These already tell you a lot — see reference.md "Anatomy of a Fabric assertion message".
2. Reproduce under Xcode debugger
open apps/ledger-live-mobile/ios/ledgerlivemobile.xcworkspace- Stop the running app first (otherwise Xcode can't attach cleanly).
- In Xcode: Cmd+8 → + → Exception Breakpoint → Objective-C → All.
- Cmd+R to build + run + attach.
- Reproduce the crash. Xcode pauses at
objc_exception_throw.
3. Identify the offending React component
In the lldb console at the bottom of Xcode:
- Pick the frame that has the offending C++/ObjC code:
bt # full backtrace, find the frame in RN code frame select N # N = the RN frame (often RCTPerformMountInstructions) - Inspect the views referenced by the failed instruction. Variable names depend on the frame — read the source displayed in Xcode. Common ones:
po parentViewDescriptor.view po oldChildViewDescriptor.view p mutation.parentTag p mutation.index p oldChildShadowView.componentName - Find where the orphan child is actually attached vs where Fabric thinks:
po [oldChildViewDescriptor.view superview] po [oldChildViewDescriptor.view accessibilityIdentifier] # = RN testID po [parentViewDescriptor.view superview] po [[parentViewDescriptor.view superview] accessibilityIdentifier] po [parentViewDescriptor.view subviews] - Climb the superview chain until you hit a
accessibilityIdentifier(= RNtestID) you recognise in source. Grep for it:
That's the RN component family. From there, read the JSX and find the conditional render / animation / library that produced the mismatch.grep -rn 'testID="<identifier>"' apps/ledger-live-mobile/src libs/ui
4. Map the native cause to a code pattern
The vast majority of Fabric assertions come from a small set of patterns. See reference.md "Common Fabric crash patterns".
5. Fix and verify Metro actually serves the fix
A common trap: Metro's file watcher dies on EMFILE: too many open files. Edits silently never reach the bundle. Always confirm Metro logged a fresh Compiled ios in Xs line after each edit (in the terminal running pnpm mobile start:ios, or wherever Metro's stdout is streaming).
If the watcher is broken, restart Metro with --reset-cache. Reload the app (Cmd+R in sim or shake → Reload).
Guardrails
- Don't guess at causes from the JS code alone — the native debugger is the source of truth.
- Don't trust "the bug only happens when flag X is on" until the user has tested both states. Correlation in mobile apps is often coincidental (cold start vs hot reload, cache state, etc.).
- Don't apply five fixes at once. Apply one, verify Metro served it, retest. Each silent failed iteration is wasted hours.
Output
- The exact React component identified as the orphan (from
accessibilityIdentifier/testID) - The pattern name (e.g. "Reanimated
withRepeaton unmount", "unstablekeyExtractor") - The minimal fix applied
- Confirmation Metro served the fix and the crash no longer reproduces
Reference
See reference.md in this folder for:
- Anatomy of a Fabric assertion message
- lldb cheatsheet for Fabric mount errors
- Catalogue of common Fabric crash patterns with code-side fixes
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
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.

