createSentryServerInstrumentation() return type is not assignable to react-router's ServerInstrumentation (mirrored types drifted since react-router 8.1.0) #23265

Description

@lasseklovstad

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*asSentryfrom"@sentry/react-router";importtype{ServerInstrumentation}from"react-router";exportconstinstrumentations: 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

  1. Install react-router@>=8.1.0 and @sentry/react-router@10.70.0.
  2. Export instrumentations from entry.server.tsx, annotated with React Router's own ServerInstrumentation type (as its instrumentation guide shows).
  3. 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:

DateEvent
2026-06-15Last update to common/types.ts (#21470, "Stabilize the instrumentation API")
2026-06-24peerDependencies bumped for react-router 8 (#21762)
2026-06-25react-router #15235 "Add instrumentation result metadata" merged
2026-06-29Shipped 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 resultInstrumentationServerHandlerResult — adds statusCode: number and metaInstrumentationResult — neither field
navigate / fetch resultInstrumentationClientRouterResult — adds metaInstrumentationResult
error in resultErrorunknown
handler info requestReadonlyRequestRequest ← what TS reports above
handler info contextPick<RouterContextProvider, "get">unknown
route handler infoReadonly<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:

exportconstinstrumentations=[Sentry.createSentryServerInstrumentation()];// orexportconstinstrumentations: ServerInstrumentation[]=[Sentry.createSentryServerInstrumentation()asServerInstrumentation,];

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.

Metadata

Metadata

Assignees

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

createSentryServerInstrumentation() return type is not assignable to react-router's ServerInstrumentation (mirrored types drifted since react-router 8.1.0) #23265

Description

@lasseklovstad

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*asSentryfrom"@sentry/react-router";importtype{ServerInstrumentation}from"react-router";exportconstinstrumentations: 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

  1. Install react-router@>=8.1.0 and @sentry/react-router@10.70.0.
  2. Export instrumentations from entry.server.tsx, annotated with React Router's own ServerInstrumentation type (as its instrumentation guide shows).
  3. 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:

DateEvent
2026-06-15Last update to common/types.ts (#21470, "Stabilize the instrumentation API")
2026-06-24peerDependencies bumped for react-router 8 (#21762)
2026-06-25react-router #15235 "Add instrumentation result metadata" merged
2026-06-29Shipped 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 resultInstrumentationServerHandlerResult — adds statusCode: number and metaInstrumentationResult — neither field
navigate / fetch resultInstrumentationClientRouterResult — adds metaInstrumentationResult
error in resultErrorunknown
handler info requestReadonlyRequestRequest ← what TS reports above
handler info contextPick<RouterContextProvider, "get">unknown
route handler infoReadonly<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:

exportconstinstrumentations=[Sentry.createSentryServerInstrumentation()];// orexportconstinstrumentations: ServerInstrumentation[]=[Sentry.createSentryServerInstrumentation()asServerInstrumentation,];

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.

Metadata

Metadata

Assignees

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

createSentryServerInstrumentation() return type is not assignable to react-router's ServerInstrumentation (mirrored types drifted since react-router 8.1.0) #23265

Description

@lasseklovstad

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*asSentryfrom"@sentry/react-router";importtype{ServerInstrumentation}from"react-router";exportconstinstrumentations: 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

  1. Install react-router@>=8.1.0 and @sentry/react-router@10.70.0.
  2. Export instrumentations from entry.server.tsx, annotated with React Router's own ServerInstrumentation type (as its instrumentation guide shows).
  3. 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:

DateEvent
2026-06-15Last update to common/types.ts (#21470, "Stabilize the instrumentation API")
2026-06-24peerDependencies bumped for react-router 8 (#21762)
2026-06-25react-router #15235 "Add instrumentation result metadata" merged
2026-06-29Shipped 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 resultInstrumentationServerHandlerResult — adds statusCode: number and metaInstrumentationResult — neither field
navigate / fetch resultInstrumentationClientRouterResult — adds metaInstrumentationResult
error in resultErrorunknown
handler info requestReadonlyRequestRequest ← what TS reports above
handler info contextPick<RouterContextProvider, "get">unknown
route handler infoReadonly<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:

exportconstinstrumentations=[Sentry.createSentryServerInstrumentation()];// orexportconstinstrumentations: ServerInstrumentation[]=[Sentry.createSentryServerInstrumentation()asServerInstrumentation,];

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.

Metadata

Metadata

Assignees

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

createSentryServerInstrumentation() return type is not assignable to react-router's ServerInstrumentation (mirrored types drifted since react-router 8.1.0) #23265

Description

@lasseklovstad

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*asSentryfrom"@sentry/react-router";importtype{ServerInstrumentation}from"react-router";exportconstinstrumentations: 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

  1. Install react-router@>=8.1.0 and @sentry/react-router@10.70.0.
  2. Export instrumentations from entry.server.tsx, annotated with React Router's own ServerInstrumentation type (as its instrumentation guide shows).
  3. 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:

DateEvent
2026-06-15Last update to common/types.ts (#21470, "Stabilize the instrumentation API")
2026-06-24peerDependencies bumped for react-router 8 (#21762)
2026-06-25react-router #15235 "Add instrumentation result metadata" merged
2026-06-29Shipped 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 resultInstrumentationServerHandlerResult — adds statusCode: number and metaInstrumentationResult — neither field
navigate / fetch resultInstrumentationClientRouterResult — adds metaInstrumentationResult
error in resultErrorunknown
handler info requestReadonlyRequestRequest ← what TS reports above
handler info contextPick<RouterContextProvider, "get">unknown
route handler infoReadonly<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:

exportconstinstrumentations=[Sentry.createSentryServerInstrumentation()];// orexportconstinstrumentations: ServerInstrumentation[]=[Sentry.createSentryServerInstrumentation()asServerInstrumentation,];

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.

Metadata

Metadata

Assignees

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

createSentryServerInstrumentation() return type is not assignable to react-router's ServerInstrumentation (mirrored types drifted since react-router 8.1.0) #23265

Description

@lasseklovstad

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*asSentryfrom"@sentry/react-router";importtype{ServerInstrumentation}from"react-router";exportconstinstrumentations: 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

  1. Install react-router@>=8.1.0 and @sentry/react-router@10.70.0.
  2. Export instrumentations from entry.server.tsx, annotated with React Router's own ServerInstrumentation type (as its instrumentation guide shows).
  3. 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:

DateEvent
2026-06-15Last update to common/types.ts (#21470, "Stabilize the instrumentation API")
2026-06-24peerDependencies bumped for react-router 8 (#21762)
2026-06-25react-router #15235 "Add instrumentation result metadata" merged
2026-06-29Shipped 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 resultInstrumentationServerHandlerResult — adds statusCode: number and metaInstrumentationResult — neither field
navigate / fetch resultInstrumentationClientRouterResult — adds metaInstrumentationResult
error in resultErrorunknown
handler info requestReadonlyRequestRequest ← what TS reports above
handler info contextPick<RouterContextProvider, "get">unknown
route handler infoReadonly<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:

exportconstinstrumentations=[Sentry.createSentryServerInstrumentation()];// orexportconstinstrumentations: ServerInstrumentation[]=[Sentry.createSentryServerInstrumentation()asServerInstrumentation,];

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.

Metadata

Metadata

Assignees

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

createSentryServerInstrumentation() return type is not assignable to react-router's ServerInstrumentation (mirrored types drifted since react-router 8.1.0) #23265

Description

@lasseklovstad

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*asSentryfrom"@sentry/react-router";importtype{ServerInstrumentation}from"react-router";exportconstinstrumentations: 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

  1. Install react-router@>=8.1.0 and @sentry/react-router@10.70.0.
  2. Export instrumentations from entry.server.tsx, annotated with React Router's own ServerInstrumentation type (as its instrumentation guide shows).
  3. 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:

DateEvent
2026-06-15Last update to common/types.ts (#21470, "Stabilize the instrumentation API")
2026-06-24peerDependencies bumped for react-router 8 (#21762)
2026-06-25react-router #15235 "Add instrumentation result metadata" merged
2026-06-29Shipped 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 resultInstrumentationServerHandlerResult — adds statusCode: number and metaInstrumentationResult — neither field
navigate / fetch resultInstrumentationClientRouterResult — adds metaInstrumentationResult
error in resultErrorunknown
handler info requestReadonlyRequestRequest ← what TS reports above
handler info contextPick<RouterContextProvider, "get">unknown
route handler infoReadonly<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:

exportconstinstrumentations=[Sentry.createSentryServerInstrumentation()];// orexportconstinstrumentations: ServerInstrumentation[]=[Sentry.createSentryServerInstrumentation()asServerInstrumentation,];

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.

Metadata

Metadata

Assignees

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

createSentryServerInstrumentation() return type is not assignable to react-router's ServerInstrumentation (mirrored types drifted since react-router 8.1.0) #23265

Description

@lasseklovstad

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*asSentryfrom"@sentry/react-router";importtype{ServerInstrumentation}from"react-router";exportconstinstrumentations: 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

  1. Install react-router@>=8.1.0 and @sentry/react-router@10.70.0.
  2. Export instrumentations from entry.server.tsx, annotated with React Router's own ServerInstrumentation type (as its instrumentation guide shows).
  3. 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:

DateEvent
2026-06-15Last update to common/types.ts (#21470, "Stabilize the instrumentation API")
2026-06-24peerDependencies bumped for react-router 8 (#21762)
2026-06-25react-router #15235 "Add instrumentation result metadata" merged
2026-06-29Shipped 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 resultInstrumentationServerHandlerResult — adds statusCode: number and metaInstrumentationResult — neither field
navigate / fetch resultInstrumentationClientRouterResult — adds metaInstrumentationResult
error in resultErrorunknown
handler info requestReadonlyRequestRequest ← what TS reports above
handler info contextPick<RouterContextProvider, "get">unknown
route handler infoReadonly<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:

exportconstinstrumentations=[Sentry.createSentryServerInstrumentation()];// orexportconstinstrumentations: ServerInstrumentation[]=[Sentry.createSentryServerInstrumentation()asServerInstrumentation,];

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.

Metadata

Metadata

Assignees

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

createSentryServerInstrumentation() return type is not assignable to react-router's ServerInstrumentation (mirrored types drifted since react-router 8.1.0) #23265

Description

@lasseklovstad

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*asSentryfrom"@sentry/react-router";importtype{ServerInstrumentation}from"react-router";exportconstinstrumentations: 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

  1. Install react-router@>=8.1.0 and @sentry/react-router@10.70.0.
  2. Export instrumentations from entry.server.tsx, annotated with React Router's own ServerInstrumentation type (as its instrumentation guide shows).
  3. 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:

DateEvent
2026-06-15Last update to common/types.ts (#21470, "Stabilize the instrumentation API")
2026-06-24peerDependencies bumped for react-router 8 (#21762)
2026-06-25react-router #15235 "Add instrumentation result metadata" merged
2026-06-29Shipped 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 resultInstrumentationServerHandlerResult — adds statusCode: number and metaInstrumentationResult — neither field
navigate / fetch resultInstrumentationClientRouterResult — adds metaInstrumentationResult
error in resultErrorunknown
handler info requestReadonlyRequestRequest ← what TS reports above
handler info contextPick<RouterContextProvider, "get">unknown
route handler infoReadonly<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:

exportconstinstrumentations=[Sentry.createSentryServerInstrumentation()];// orexportconstinstrumentations: ServerInstrumentation[]=[Sentry.createSentryServerInstrumentation()asServerInstrumentation,];

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.

Metadata

Metadata

Assignees

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions