Skip to content

Reload the application once so first-run breakpoints are hit - #1

Merged
teoboetti merged 1 commit into
masterfrom
fix/first-run-breakpoints
Sep 28, 2026
Merged

teoboetti merged 1 commit into
masterfrom
fix/first-run-breakpoints

Conversation

@teoboetti

Copy link
Copy Markdown
Owner

Breakpoints set before the first run of a reactnativedirect session are never hit. Reloading the app by hand makes the same breakpoints work, which is the workaround users land on today.

Cause

A launch installs and starts the app, which finishes evaluating its bundle well before the CDP proxy manages to attach. Hermes replays Debugger.scriptParsed on Debugger.enable, so breakpoints registered for that first run resolve and look bound in the UI — but the code they belong to has already executed, so nothing stops.

There is no pause-on-load to wait for. Hermes answers Runtime.runIfWaitingForDebugger with:

{"error":{"code":-32601,"message":"Unsupported method 'Runtime.runIfWaitingForDebugger'"},"id":1}

so the only lever is to run the bundle again once the debugger is ready.

Change

HermesCDPMessageHandler sends a single Page.reload after the debugger goes quiet following its initial Debugger.setBreakpointByUrl / Debugger.setBreakpoint requests (300 ms debounce, once per session, cancelled on close).

Reloads are driven by the device — the nativePageReloads capability reported in /json/list — so the debugger stays attached across the reload and the breakpoints re-bind. Verified against a live RN 0.87.1 iOS target:

Page.reload → {"result":{},"id":2}

The request is sent out of band with an id the debugger never issued, so js-debug discards the reply via the unknown-response-id path in _processResponse rather than mis-attributing it.

If no breakpoints are set at launch, no reload is sent.

Validation

  • tsc --noEmit clean, gulp lint reports no new warnings
  • npm test — 465 passing, 0 failing (run npx gulp first, otherwise the commandsRegistered test fails on a missing dist/rn-extension)
  • 5 new unit tests in test/cdp-proxy/hermesCDPMessageHandler.test.ts: reload fires, a burst coalesces into one, no second reload per session, cancelled on disconnect, breakpoint passthrough unaffected
  • Manually verified end to end on React Native 0.87.1, iOS simulator, Hermes

Note

Independent of microsoft#2782 and touches no files in common, but in practice both are needed on RN >= 0.76: without microsoft#2782 the proxy never connects at all, so there is no session in which this reload could help.

A launch installs and starts the app, which finishes evaluating its bundle
well before the CDP proxy manages to attach. Hermes replays scriptParsed on
Debugger.enable, so breakpoints registered for that first run resolve and
look bound, but the code they belong to has already executed and they are
never reached. Reloading by hand makes them work, which is what users hit
today.

Hermes has no pause-on-load to wait for: it answers
Runtime.runIfWaitingForDebugger with "Unsupported method" (-32601), so the
only lever is to run the bundle again once the debugger is ready. Send a
single Page.reload after the debugger goes quiet following its initial
breakpoint requests. Reloads are driven by the device (the nativePageReloads
capability), so the debugger stays attached and the breakpoints re-bind.

The request is sent out of band with an id the debugger never issued, so it
discards the reply as an unknown response id.
@teoboetti
teoboetti force-pushed the fix/first-run-breakpoints branch from 065586a to 0dfc8e2 Compare September 28, 2026 13:22
@teoboetti

Copy link
Copy Markdown
Owner Author

Superseded by #2, which carries this same commit alongside the Origin and listen-race fixes and the build tooling.

@teoboetti
teoboetti merged commit dc29b6b into master Sep 28, 2026
@teoboetti
teoboetti deleted the fix/first-run-breakpoints branch September 28, 2026 13:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant