Skip to content

Runtime injection does not instrument modules loaded by tsx on Node 24.13+ #24787

Closed

Description

@JPeer264

Follow up to #24343

From Node 24.13 / 25.1, registerDiagnosticsChannelInjection() in @sentry/server-runtime-injection registers Module.registerHooks({ resolve, load }) and, unlike the Module.register path for older Node versions, does not patch Module.prototype._compile. Runners that compile CommonJS themselves (tsx, ts-node) take over require, so the files they load never reach the sync load hook and stay uninstrumented.

On Node 24.21, a script that calls Sentry.init() and then requires express and mysql records __SENTRY_ORCHESTRION__.runtime as ["express","express"] under plain node, and [] under tsx. Every user who runs their app with tsx or ts-node on Node 24.13+ loses channel-based spans today, for example the express route name on http.server segments.

In the tsx-express E2E app on Node 24.21, 8 of 10 tests failed: error events without the route segment, API route spans, MCP handler spans and all four tRPC tests.

A first fix in #24343 (later removed from that PR) added the _compile patch on the registerHooks path. On its own it transforms every file twice when a plain require goes through both the sync hook and _compile, which records each module twice (runtime=["dataloader","dataloader"]) and broke the esbuild orchestrion suite and the Deno @sentry/deno/import tests. Skipping _compile for the files the sync hook already transformed fixed that, and the unit, esbuild and Deno suites passed with it.

When this is fixed, remove the volta.node pin (20.19.5) from the tsx-express E2E app, which #24343 added so its E2E tests keep running on Node 20.

Activity

  1. linear-code commented on Sep 28, 2026

    @linear-code
  2. jpdefo commented on Oct 14, 2026

    @jpdefo
    Contributor

    I reproduced this on current develop (51b1946) with Node 24.21.0, the built original @sentry/server-runtime-injection package, and a real dataloader operation. Plain Node emits one dataloader load tracing-channel event, while the same fixture with tsx/cjs emits none, even though the load completes in both cases.

    I'd like to work on restoring the CommonJS compile fallback on stable-hook Node versions, with exact-once coverage to prevent double instrumentation on ordinary loads and controls for the existing runtime paths. AI assistance was used for investigation and test preparation.

  3. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Oct 14, 2026
  4. JPeer264 commented on Oct 14, 2026

    @JPeer264
    MemberAuthor

    @jpdefo thanks for double checking

    I'd like to work on restoring the CommonJS compile fallback on stable-hook Node versions, with exact-once coverage to prevent double instrumentation on ordinary loads and controls for the existing runtime paths.

    Do you mean you want to work on this ticket? Sorry I can't really tell. Otherwise I'll take over and would start to work on it

  5. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Oct 14, 2026
  6. jpdefo commented on Oct 14, 2026

    @jpdefo
    Contributor

    Yes, I am working on this ticket. The fix and regression coverage are ready locally and have completed five independent reviews. I am finishing the required project checks and human review before opening a draft PR.

  7. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Oct 14, 2026
  8. added a commit that references this issue on Oct 14, 2026
    9d5002b
  9. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Oct 14, 2026
  10. added a commit that references this issue on Oct 16, 2026
    50ed82b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions