scroll-restoration registers pagehide with a bare addEventListener, which breaks under a patched EventTarget
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 1/5
- Thời gian dự kiến
- Dưới một giờ
- Mức phù hợp với người mới
- 78/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Ít trao đổi
- Công nghệ
- typescript
- Lĩnh vực
- frontend
Hướng nghiên cứu
Bắt đầu trong packages/router-core/src/scroll-restoration.ts tại phần đăng ký pagehide quanh dòng 222, và so sánh với listener document đủ điều kiện ở phía trên. Tái hiện lỗi bằng app tối giản được liên kết, sử dụng scrollRestoration và instrumentation EventTarget đã được patch. Hoàn tất khi việc xây dựng router thành công và trang được render với handler pagehide được đăng ký trên window.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Which project does this relate to?
Router
Describe the bug
setupScrollRestoration registers its pagehide handler with an unqualified call:
// packages/router-core/src/scroll-restoration.ts:222
addEventListener('pagehide', () => { … })
From an ES module that passes this === undefined. The native method resolves an undefined receiver to the global per WebIDL, so the call is legal and works normally — but only as long as nothing has replaced EventTarget.prototype.addEventListener with a plain JS function that reads its receiver.
TypeError: Invalid value used as weak map key
at WeakMap.set (<anonymous>)
at UserInteractionInstrumentation.addPatchedListener (…/@opentelemetry_instrumentation-user-interaction.js:487:19)
at addEventListenerPatched (…/@opentelemetry_instrumentation-user-interaction.js:533:16)
at setupScrollRestoration (…/@tanstack_react-router.js:1549:3)
at RouterCore.update (…/@tanstack_react-router.js:3133:25)
at new RouterCore (…/@tanstack_react-router.js:3817:8)
at new Router (…/@tanstack_react-router.js:6850:3)
at createRouter (…/@tanstack_react-router.js:6846:9)
at …/src/main.tsx:100:16
The throw is uncaught and synchronous, out of createRouter() — nothing renders at all. #root stays empty and the body holds two elements (the root div and the module script). There is also no useful console output: React reports this class of failure as a generic An error occurred in the <AwaitInner> component, logged via console.error("%s\n\n%s", …), so the substitution args carrying the real error are dropped by every forwarder in the chain. The stack above only exists because the reproducer hooks window.onerror.
The instrumentation is at fault for throwing on a legal call, and that is being fixed upstream (open-telemetry/opentelemetry-js-contrib#3639, PR telemetry/opentelemetry-js-contrib#3653). But the
bare call is the only one of its kind in the package — every other listener registration qualifies its receiver, including document.addEventListener two lines above this one — and it is fragile against any library that patches EventTarget (OTel, Zone.js, Sentry, analytics wrappers). window. on line 222 makes router construction independent of the WebIDL fallback.
Complete minimal reproducer
https://github.com/typedrat/tanstack-router-otel-user-interaction-repro
Steps to Reproduce the Bug
git clone https://github.com/typedrat/tanstack-router-otel-user-interaction-repro && cd tanstack-router-otel-user-interaction-repronpm install && npm run dev- Open http://localhost:5199 in a Chromium-based browser.
- The page is blank and the
TypeErrorabove is thrown. The app is ~70 lines in a singlesrc/main.tsx: two routes,createRouter({ routeTree, scrollRestoration: true }), and oneregisterInstrumentations(…)call.
Two independent one-line toggles each make it render, which isolates the
interaction:
| variant | result |
|---|---|
instrumentation registered, scrollRestoration: true |
blank page, TypeError |
instrumentation registered, scrollRestoration unset |
renders |
registerInstrumentations(…) commented out, scrollRestoration: true |
renders |
So this only affects apps that opt into scrollRestoration — that is the flag on
setupScrollRestoration's shouldSetupScrollRestoration guard, and the bare call
sits inside it.
Expected behavior
The router registers its pagehide handler on window and constructs normally regardless of what has patched EventTarget.prototype.addEventListener.
Screenshots or Videos
No response
Platform
- Router / Start Version:
@tanstack/react-router1.170.18 (@tanstack/router-core1.171.15; the call site is unchanged onmain) - OS: Linux
- Browser: Chrome
- Browser Version: 151.0.7922.108 (headless)
- Bundler: vite
- Bundler Version: 8.2.1
Also present with React 19.2.8, @opentelemetry/instrumentation-user-interaction 0.65.0, @opentelemetry/sdk-trace-web 2.10.0, and no zone.js in the tree. The no-Zone patch path is the one that breaks.
Additional context
Triggered in a real app by @opentelemetry/auto-instrumentations-web >= 0.66.0, which is the release that moved its instrumentation-user-interaction dependency to ^0.65.0.
We've worked around it by wrapping the upstream wrapper to reinstate the WebIDL fallback, and I can confirm that does resolve the issue.
- Ngôn ngữ chính
- TypeScript
- Star
- 15.1k
- Fork
- 1.9k
- Merge trung bình
- 1 ngày 19 giờ
- Pull request đã merge (30 ngày)
- 136
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của TanStack/router
-
information needed
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 90/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
lazyRouteComponent reload guard key collides on Safari, capping stale-deploy recovery at one per tab Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
-
information needed
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Tất cả issue của TanStack/router
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
Eynzof/Hermes-CN-Desktop#610 ·
-
[Bug]: Matrix progress drafts fail with "Matrix runtime not initialized" during tool activity Đang mởbug clawsweeper:linked-pr-open clawsweeper:needs-live-repro clawsweeper:no-new-fix-pr impact:message-loss issue-rating: 🐚 platinum hermit P2 regression
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
Client support matrix inclusion Đang mởenhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
-
calcite-components needs triage refactor
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
Esri/calcite-design-system#15203 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 90/100
danielmiessler/LifeOS#2218 ·