{"record":{"id":"2f358729f68428b9","repo":"leptos-rs/leptos","slug":"you-cannot-use-suspend-on-an-attribute-outside-sus-2f3587","errorCode":null,"errorMessage":"You cannot use Suspend on an attribute outside Suspense","messagePattern":"You cannot use Suspend on an attribute outside Suspense","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tachys/src/reactive_graph/style.rs","lineNumber":515,"sourceCode":"    style_reactive!(ArcStore, <V>, V, false, ArcStore<V>: Get<Value = V>);\n    style_reactive!(ArcField, <V>, V, false, ArcField<V>: Get<Value = V>);\n}\n/*\nimpl<Fut> IntoStyle for Suspend<Fut>\nwhere\n    Fut: Clone + Future + Send + 'static,\n    Fut::Output: IntoStyle,\n{\n    type AsyncOutput = Fut::Output;\n    type State = Rc<RefCell<Option<<Fut::Output as IntoStyle>::State>>>;\n    type Cloneable = Self;\n    type CloneableOwned = Self;\n\n    fn to_html(self, style: &mut String) {\n        if let Some(inner) = self.inner.now_or_never() {\n            inner.to_html(style);\n        } else {\n            panic!(\"You cannot use Suspend on an attribute outside Suspense\");\n        }\n    }\n\n    fn hydrate<const FROM_SERVER: bool>(\n        self,\n        el: &crate::renderer::types::Element,\n    ) -> Self::State {\n        let el = el.to_owned();\n        let state = Rc::new(RefCell::new(None));\n        reactive_graph::spawn_local_scoped({\n            let state = Rc::clone(&state);\n            async move {\n                *state.borrow_mut() =\n                    Some(self.inner.await.hydrate::<FROM_SERVER>(&el));\n                self.subscriber.forward();\n            }\n        });\n        state","sourceCodeStart":497,"sourceCodeEnd":533,"githubUrl":"https://github.com/leptos-rs/leptos/blob/32d20f6c9d517451d77beb68d88c7716823dac41/tachys/src/reactive_graph/style.rs#L497-L533","documentation":"Same family as the class variant: a Suspend-wrapped style attribute value is a future, and to_html can only render values available synchronously via now_or_never(). Outside a Suspense context there is nothing to await the future, so the style attribute panics during HTML string generation.","triggerScenarios":"Using Suspend(async expression) as a style attribute during SSR/dry rendering without a surrounding Suspense boundary.","commonSituations":"Async-computed inline styles (theme data fetched async) rendered on the server; converting a style: attr to an async source without adding Suspense.","solutions":["Wrap the view containing the async style attribute in <Suspense>.","Precompute the style value so it is synchronous at render time.","Move the async fetch above the render (e.g. load data in a resource awaited within Suspense and pass the plain string down)."],"exampleFix":"// before\nview! { <div style=Suspend(async move { theme_style().await }) /> }\n// after\nview! {\n  <Suspense fallback=|| ()>\n    <div style=Suspend(async move { theme_style().await }) />\n  </Suspense>\n}","handlingStrategy":"validation","validationCode":"fn style_ready(s: &Suspend<impl Future>) -> bool { s.clone().inner_now_or_never().is_some() } // if false, you need Suspense","typeGuard":"fn is_plain_style(v: &str) -> bool { true } // favor &str/Read-derived styles over Suspend","tryCatchPattern":"std::panic::catch_unwind(|| to_html(&view)).map_err(|_| /* wrap in Suspense and retry */)","preventionTips":["Wrap async style attributes in a Suspense boundary.","Resolve theme/style data before the initial SSR render.","Keep inline styles synchronous during SSR.","Add an SSR smoke test that renders every component to HTML."],"tags":["ssr","suspense","async-attribute"],"backgroundTag":"suspend-attribute-outside-suspense","analyzedSha":"32d20f6c9d517451d77beb68d88c7716823dac41","analyzedAt":"2026-09-01T18:55:42.580Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T01:17:15.007Z"}