Skip to content

@sentry/react-router 11: build-time instrumentation inlines CommonJS that default-imports @sentry/core; server crashes at startup #25339

Open

Description

@mlavesther

This issue was written with Claude Opus 5.5 (Anthropic) and reviewed by a human before it was filed.

Is there an existing issue for this?

How do you use Sentry?

Sentry Saas (sentry.io)

Which SDK are you using?

@sentry/react-router

SDK Version

11.7.0

Framework Version

React Router 7.18.4 (framework mode, custom Express server); also reproduced on React Router 8.4.0. Vite 7.3.7, Node.js 22.23.3.

Link to Sentry event

No response

Reproduction Example/SDK Setup

vite.config.ts adds the Sentry plugin only for production builds that have an auth token, and does not set buildTimeInstrumentation:

sentryReactRouter(
  {
    org: "<org>",
    project: "<project>",
    authToken: process.env.SENTRY_AUTH_TOKEN,
    telemetry: false,
    release: process.env.SENTRY_RELEASE ? { name: process.env.SENTRY_RELEASE } : undefined,
  },
  config,
),

Sentry is initialised before the app via NODE_OPTIONS='--import ./instrument.server.mjs' (Sentry.init from @sentry/react-router, plus nodeProfilingIntegration). The server then loads the build with await import("./build/server/index.js").

Steps to Reproduce

  1. Build with SENTRY_AUTH_TOKEN set and NODE_ENV unset (our CI Docker build). sentryReactRouter then adds sentryOrchestrionPlugin.
  2. Start the server: node --import ./instrument.server.mjs server.js.

We reproduced this deterministically in our app, locally and in production. We have not built a minimal standalone project.

Expected Result

The server boots, as it did on 10.x.

Actual Result

The server process exits while importing the server build:

file:///app/build/server/assets/app-<hash>.js:26
import require$$0$1, { GLOBAL_OBJ, getAsyncContextStrategy, getMainCarrier, debug, getActiveSpan, spanIsIgnored, getRootSpan, withActiveSpan, captureException, SPAN_STATUS_ERROR, isObjectLike, getClient, waitForTracingChannelBinding, addNonEnumerableProperty, defineIntegration, hasSpanStreamingEnabled, startInactiveSpan } from "@sentry/core";
       ^^^^^^^^^^^^
SyntaxError: The requested module '@sentry/core' does not provide an export named 'default'
    at ModuleJob._instantiate (node:internal/modules/esm/module_job:226:21)

sentryOrchestrionPlugin (@sentry/server-utils/orchestrion/vite) sets ssr.noExternal to the instrumented modules plus @sentry/server-utils. That bundles CommonJS code calling require("@sentry/core"), and Rollup's CommonJS interop rewrites the call as a default import. @sentry/core stays external and ESM-only, so the default import fails at runtime. A comment in that plugin already names this failure mode for @sentry/server-utils; this is the same failure for @sentry/core.

Builds without an auth token never add the plugin, so they import fine. In our setup that meant every local and CI build passed, and only the production image crashed.

Additional Context

Priority

React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it.

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