Which SDK are you using?
@sentry/react-router
SDK Version
10.69.0 — also verified still present in the 10.70.0 tag's source (packages/react-router/src/common/types.ts is byte-identical)
Framework Version
react-router 8.3.0 (regression introduced in 8.1.0, see below)
Reproduction Example/SDK Setup
On any React Router 8.1+ framework-mode app with strict TypeScript, following the instrumentation docs in entry.server.tsx:
import * as Sentry from "@sentry/react-router";
import type { ServerInstrumentation } from "react-router";
export const instrumentations: ServerInstrumentation[] = [
Sentry.createSentryServerInstrumentation(),
];
No Sentry.init specifics are relevant — this is a compile-time-only failure and reproduces regardless of runtime config.
Steps to Reproduce
- Install
react-router@>=8.1.0 and @sentry/react-router@10.70.0.
- Export
instrumentations from entry.server.tsx, annotated with React Router's own ServerInstrumentation type (as its instrumentation guide shows).
- Run
tsc --noEmit.
Expected Result
createSentryServerInstrumentation() is assignable to react-router's ServerInstrumentation, so the documented setup typechecks.
Actual Result
error TS2322: Type '@sentry/react-router/build/types/common/types".ServerInstrumentation'
is not assignable to type 'react-router/dist/production/lib/router/instrumentation".ServerInstrumentation'.
Types of property 'handler' are incompatible.
Type '((handler: InstrumentableRequestHandler) => void) | undefined' is not assignable to type 'InstrumentRequestHandlerFunction | undefined'.
Type '(handler: InstrumentableRequestHandler) => void' is not assignable to type 'InstrumentRequestHandlerFunction'.
Types of parameters 'handler' and 'handler' are incompatible.
Type 'InstrumentableRequestHandler' is not assignable to type '@sentry/react-router/build/types/common/types".InstrumentableRequestHandler'.
Additional Context
Root cause: the mirrored type file has drifted
packages/react-router/src/common/types.ts is a hand-maintained copy of React Router's instrumentation types, and carries this note:
Derived from React Router's instrumentations API. If React Router changes these types, this file must be updated.
React Router changed them and the copy wasn't re-synced:
| Date |
Event |
| 2026-06-15 |
Last update to common/types.ts (#21470, "Stabilize the instrumentation API") |
| 2026-06-24 |
peerDependencies bumped for react-router 8 (#21762) |
| 2026-06-25 |
react-router #15235 "Add instrumentation result metadata" merged |
| 2026-06-29 |
Shipped in react-router@8.1.0 |
Concrete divergences (react-router 8.3.0 vs @sentry/react-router 10.70.0)
|
react-router |
@sentry/react-router |
| request handler result |
InstrumentationServerHandlerResult — adds statusCode: number and meta |
InstrumentationResult — neither field |
| navigate / fetch result |
InstrumentationClientRouterResult — adds meta |
InstrumentationResult |
error in result |
Error |
unknown |
handler info request |
ReadonlyRequest |
Request ← what TS reports above |
handler info context |
Pick<RouterContextProvider, "get"> |
unknown |
| route handler info |
Readonly<Omit<LoaderFunctionArgs, "request" | "context"> & {...}> — pattern and url required |
{ params, pattern?, unstable_pattern?, context? } |
Runtime appears unaffected
Reading createServerInstrumentation.ts at the 10.70.0 tag, the instrumentation only consumes info.request.method, info.request.url (via getPathFromRequest), info.pattern ?? info.unstable_pattern, and result.status / result.error instanceof Error. React Router 8.3.0 supplies all of those — pattern is a required field on DataFunctionArgs, and the added statusCode/meta fields are simply ignored. So this looks like a types-only problem, with spans and errors still reported correctly. Worth confirming on your side, though, since statusCode is now available and currently invisible to the SDK.
Workaround
Dropping the annotation, or a single cast, both compile:
export const instrumentations = [Sentry.createSentryServerInstrumentation()];
// or
export const instrumentations: ServerInstrumentation[] = [
Sentry.createSentryServerInstrumentation() as ServerInstrumentation,
];
Suggested fix
Beyond re-syncing the file, the mirroring itself is the recurring failure mode — this will drift again on the next React Router change. Since react-router is already a peer dependency, importing its exported instrumentation types (ServerInstrumentation, ClientInstrumentation, InstrumentableRequestHandler, InstrumentableRoute) would make the mismatch impossible. If the copy has to stay for peer-range reasons, a type-level assignability assertion in the test suite against the mirrored shapes would at least turn the drift into a CI failure rather than a downstream compile error.
Which SDK are you using?
@sentry/react-routerSDK Version
10.69.0 — also verified still present in the
10.70.0tag's source (packages/react-router/src/common/types.tsis byte-identical)Framework Version
react-router 8.3.0 (regression introduced in 8.1.0, see below)
Reproduction Example/SDK Setup
On any React Router 8.1+ framework-mode app with
strictTypeScript, following the instrumentation docs inentry.server.tsx:No Sentry.init specifics are relevant — this is a compile-time-only failure and reproduces regardless of runtime config.
Steps to Reproduce
react-router@>=8.1.0and@sentry/react-router@10.70.0.instrumentationsfromentry.server.tsx, annotated with React Router's ownServerInstrumentationtype (as its instrumentation guide shows).tsc --noEmit.Expected Result
createSentryServerInstrumentation()is assignable toreact-router'sServerInstrumentation, so the documented setup typechecks.Actual Result
Additional Context
Root cause: the mirrored type file has drifted
packages/react-router/src/common/types.tsis a hand-maintained copy of React Router's instrumentation types, and carries this note:React Router changed them and the copy wasn't re-synced:
common/types.ts(#21470, "Stabilize the instrumentation API")react-router@8.1.0Concrete divergences (react-router 8.3.0 vs @sentry/react-router 10.70.0)
InstrumentationServerHandlerResult— addsstatusCode: numberandmetaInstrumentationResult— neither fieldInstrumentationClientRouterResult— addsmetaInstrumentationResulterrorin resultErrorunknownrequestReadonlyRequestRequest← what TS reports abovecontextPick<RouterContextProvider, "get">unknownReadonly<Omit<LoaderFunctionArgs, "request" | "context"> & {...}>—patternandurlrequired{ params, pattern?, unstable_pattern?, context? }Runtime appears unaffected
Reading
createServerInstrumentation.tsat the10.70.0tag, the instrumentation only consumesinfo.request.method,info.request.url(viagetPathFromRequest),info.pattern ?? info.unstable_pattern, andresult.status/result.error instanceof Error. React Router 8.3.0 supplies all of those —patternis a required field onDataFunctionArgs, and the addedstatusCode/metafields are simply ignored. So this looks like a types-only problem, with spans and errors still reported correctly. Worth confirming on your side, though, sincestatusCodeis now available and currently invisible to the SDK.Workaround
Dropping the annotation, or a single cast, both compile:
Suggested fix
Beyond re-syncing the file, the mirroring itself is the recurring failure mode — this will drift again on the next React Router change. Since
react-routeris already a peer dependency, importing its exported instrumentation types (ServerInstrumentation,ClientInstrumentation,InstrumentableRequestHandler,InstrumentableRoute) would make the mismatch impossible. If the copy has to stay for peer-range reasons, a type-level assignability assertion in the test suite against the mirrored shapes would at least turn the drift into a CI failure rather than a downstream compile error.