{"record":{"id":"0639e0544b35462d","repo":"yewstack/yew","slug":"failed-to-render-application","errorCode":null,"errorMessage":"failed to render application","messagePattern":"failed to render application","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/yew/src/server_renderer.rs","lineNumber":262,"sourceCode":"            create_props,\n            hydratable,\n            rt,\n        } = self;\n\n        let (tx, rx) = futures::channel::oneshot::channel();\n        let create_task = move || async move {\n            let props = create_props();\n            let s = LocalServerRenderer::<COMP>::with_props(props)\n                .hydratable(hydratable)\n                .render()\n                .await;\n\n            let _ = tx.send(s);\n        };\n\n        Self::spawn_rendering_task(rt, create_task);\n\n        rx.await.expect(\"failed to render application\")\n    }\n\n    /// Renders Yew Application to a String.\n    pub async fn render_to_string(self, w: &mut String) {\n        let mut s = self.render_stream();\n\n        while let Some(m) = s.next().await {\n            w.push_str(&m);\n        }\n    }\n\n    #[inline]\n    fn spawn_rendering_task<F, Fut>(rt: Option<Runtime>, create_task: F)\n    where\n        F: 'static + Send + FnOnce() -> Fut,\n        Fut: Future<Output = ()> + 'static,\n    {\n        match rt {","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/yewstack/yew/blob/0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3/packages/yew/src/server_renderer.rs#L244-L280","documentation":"ServerRenderer::render() runs the entire SSR pass on a spawned local task and receives the resulting String over a oneshot channel; this expect fires when rx.await returns Err, meaning the sender was dropped without sending. That happens only when the render task died - a panic inside component rendering, property creation, or a hook on the server side tore the task down before it could call tx.send(). The message is a symptom; the real error is the earlier panic in the server logs.","triggerScenarios":"Any panic during server rendering: components calling browser-only APIs (gloo::utils::window()/document(), web_sys access) without guards; expects/unwraps inside create_props or view code; a custom runtime passed via with_runtime being dropped before the render completes.","commonSituations":"Porting a CSR app to SSR without is_browser()/cfg guards; unwrapping request data when building props; custom tokio runtimes shut down early; effects or hooks that assume a browser environment.","solutions":["Read the server logs immediately above this message - the panic that killed the render task is the actual error","Guard all browser access with if yew::is_browser() { ... } or #[cfg(target_arch = \"wasm32\")] blocks","Unit-test create_props and component view code compiled for the server target","If using with_runtime, keep the runtime alive until render() completes"],"exampleFix":"// before: panics on the server - there is no window during SSR\nfn view(&self, _ctx: &Context<Self>) -> Html {\n    let h = gloo::utils::window().inner_height();\n    // ...\n}\n\n// after: branch on environment\nfn view(&self, _ctx: &Context<Self>) -> Html {\n    let h = if yew::is_browser() {\n        Some(gloo::utils::window().inner_height())\n    } else {\n        None\n    };\n    // ...\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Turn the channel panic into a recoverable error and fall back to a CSR shell:\nuse futures::FutureExt;\nuse std::panic::AssertUnwindSafe;\n\nlet out = AssertUnwindSafe(renderer.render()).catch_unwind().await;\nmatch out {\n    Ok(html) => response.body(html),\n    Err(_) => {\n        tracing::error!(\"SSR task panicked; see panic log above\");\n        response.body(client_side_shell())\n    }\n}","preventionTips":["Install a panic hook that logs the task panic - the expect here only reports the dead channel","Guard every browser API call with yew::is_browser() or cfg(target_arch = \"wasm32\")","Keep custom runtimes passed to with_runtime alive until render() completes","Compile and run component tests against the server target in CI"],"tags":["ssr","server-rendering","panic","tokio"],"backgroundTag":"server-render-task-panic","analyzedSha":"0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3","analyzedAt":"2026-08-22T21:16:31.212Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}