{"record":{"id":"e376c0a398b8fd97","repo":"DioxusLabs/dioxus","slug":"should-be-run-in-a-context-with-a-window-object","errorCode":null,"errorMessage":"should be run in a context with a `Window` object (dioxus cannot be run from a web worker)","messagePattern":"should be run in a context with a `Window` object \\(dioxus cannot be run from a web worker\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/web/src/history.rs","lineNumber":363,"sourceCode":"    pub x: f64,\n    pub y: f64,\n}\n\nimpl ScrollPosition {\n    pub(crate) fn of_window(window: &Window) -> Self {\n        Self {\n            x: window.scroll_x().unwrap_or_default(),\n            y: window.scroll_y().unwrap_or_default(),\n        }\n    }\n\n    pub(crate) fn scroll_to(&self, window: Window) {\n        let Self { x, y } = *self;\n        let f = Closure::wrap(\n            Box::new(move || window.scroll_to_with_x_and_y(x, y)) as Box<dyn FnMut()>\n        );\n        web_sys::window()\n            .expect(\"should be run in a context with a `Window` object (dioxus cannot be run from a web worker)\")\n            .request_animation_frame(&f.into_js_value().unchecked_into())\n            .expect(\"should register `requestAnimationFrame` OK\");\n    }\n}\n\npub(crate) fn replace_state_with_url(\n    history: &History,\n    value: &[f64; 2],\n    url: Option<&str>,\n) -> Result<(), JsValue> {\n    let position = js_sys::Array::new();\n    position.push(&JsValue::from(value[0]));\n    position.push(&JsValue::from(value[1]));\n    history.replace_state_with_url(&position, \"\", url)\n}\n\npub(crate) fn push_state_and_url(\n    history: &History,","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/DioxusLabs/dioxus/blob/393d190a801ccb441d41923e232289b4f8a5c669/packages/web/src/history.rs#L345-L381","documentation":"`ScrollPosition::scroll_to` - used by the router to restore scroll after navigation - wraps `window.scrollTo(x, y)` in a requestAnimationFrame callback and re-fetches `web_sys::window()` with an expect whose message states the constraint outright: dioxus cannot run from a web worker. In any window-less context (worker, SSR), scroll restoration panics.","triggerScenarios":"Router scroll restoration (or a direct scroll_to call) executing in a web worker; scroll restore triggered after the browsing context is gone.","commonSituations":"The same misconfigurations that break WebHistory construction: worker-hosted UI, SSR builds linking web renderer code, headless tests touching navigation.","solutions":["Keep the router and its scroll restoration on the browser main thread","Disable scroll restoration (construct the history with do_scroll_restoration=false) in environments where scrolling cannot work","cfg-gate web routing code out of server builds"],"exampleFix":"// before: scroll restoration enabled, panics in worker contexts\nlet history = WebHistory::new(None, true);\n// after: disable it where the Window/rAF path cannot run\nlet history = WebHistory::new(None, false);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"fn can_restore_scroll() -> bool {\n    web_sys::window().is_some()\n}","tryCatchPattern":null,"preventionTips":["Never host dioxus-web in a web worker - the message itself states this constraint","Disable scroll restoration (do_scroll_restoration=false) in any environment where the Window/rAF path cannot run","cfg-gate web routing code out of server builds so scroll restoration cannot execute there"],"tags":["dioxus-web","router","scroll-restoration","window","web-worker","panic"],"backgroundTag":null,"analyzedSha":"393d190a801ccb441d41923e232289b4f8a5c669","analyzedAt":"2026-08-16T11:27:45.815Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}