{"record":{"id":"68caa6f6539706c1","repo":"leptos-rs/leptos","slug":"couldn-t-serialize-island-props","errorCode":null,"errorMessage":"couldn't serialize island props","messagePattern":"couldn't serialize island props","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"leptos_macro/src/component.rs","lineNumber":306,"sourceCode":"            #[cfg(not(feature = \"tracing\"))]\n            {\n                (quote!(), quote!(), quote!(), quote!())\n            }\n        };\n\n        let component_id = name.to_string();\n        let hydrate_fn_name = is_island.then(|| {\n            use std::hash::{Hash, Hasher};\n\n            let mut hasher = DefaultHasher::new();\n            island.hash(&mut hasher);\n            let caller = hasher.finish() as usize;\n            Ident::new(&format!(\"{component_id}_{caller:?}\"), name.span())\n        });\n\n        let island_serialize_props = if is_island_with_other_props {\n            quote! {\n                let _leptos_ser_props = ::leptos::serde_json::to_string(&props).expect(\"couldn't serialize island props\");\n            }\n        } else {\n            quote! {}\n        };\n        let island_serialized_props = if is_island_with_other_props {\n            quote! {\n                .with_props( _leptos_ser_props)\n            }\n        } else {\n            quote! {}\n        };\n\n        let body_name = unmodified_fn_name_from_fn_name(&body_name);\n        let body_expr = if is_island {\n            quote! {\n                ::leptos::reactive::owner::Owner::new().with(|| {\n                    ::leptos::reactive::owner::Owner::with_hydration(move || {\n                        ::leptos::tachys::reactive_graph::OwnedView::new({","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/leptos-rs/leptos/blob/32d20f6c9d517451d77beb68d88c7716823dac41/leptos_macro/src/component.rs#L288-L324","documentation":"In the #[component] macro, when a component is an island that has props beyond those captured on the client (is_island_with_other_props), the macro generates code that serializes all props to JSON at runtime via serde_json::to_string(&props).expect(\"couldn't serialize island props\"). This panics if any prop type is not JSON-serializable at runtime (e.g. contains non-serializable data like functions, channels, or unserializable custom types).","triggerScenarios":"Declaring an #[component(island = true)] whose props include a type that fails Serialize at runtime — serialize returns Err (map keys not strings, unsupported types, poisoned serializer) — then hitting the generated expect during the island render path.","commonSituations":"Island props containing Rc/RefCell/callbacks or types with #[serde(skip)]-incompatible shapes; closures or generic types without Serialize bound; serde version mismatch producing non-string map keys.","solutions":["Make every island prop implement Serialize (and Deserialize for hydration); add #[derive(Serialize, Deserialize)] to custom types","Remove non-serializable props (callbacks, Rc/NodeRef) from islands or pass only primitive/serializable data","Avoid non-string map keys in props (use HashMap<String, _> not HashMap<MyEnum, _> unless keys serialize as strings)","Handle serialization explicitly instead of relying on the macro's expect: serialize manually and pass as a String prop"],"exampleFix":"// before\n#[component]\nfn MyIsland(#[prop(into)] data: MyData) -> impl IntoView { ... } // MyData: no Serialize\n// after\n#[derive(Clone, serde::Serialize, serde::Deserialize)]\nstruct MyData { id: u32, name: String }\n#[component]\nfn MyIsland(data: MyData) -> impl IntoView { ... }","handlingStrategy":"validation","validationCode":"// Pre-validate island props serializability in a test:\nlet _ = serde_json::to_string(&props)\n    .unwrap_or_else(|e| panic!(\"island props not serializable: {e}\"));","typeGuard":"fn is_island_serializable<T: serde::Serialize>(props: &T) -> bool {\n    serde_json::to_string(props).is_ok()\n}","tryCatchPattern":"// The expect panics; serialize yourself before the macro path and handle the Result:\nmatch serde_json::to_string(&props) {\n    Ok(json) => { /* pass json as a String prop */ }\n    Err(e) => log::error!(\"island props serialization failed: {e}\"),\n}","preventionTips":["Derive Serialize (+Deserialize) on every island prop type","Never put callbacks, Rc, NodeRef, or channels in island props","Use HashMap<String, T> (string keys) in props","Add a unit test that serializes each island's props struct"],"tags":["islands","serialization","serde","macro","panic"],"backgroundTag":"property-serialization-failed","analyzedSha":"32d20f6c9d517451d77beb68d88c7716823dac41","analyzedAt":"2026-09-01T18:55:42.580Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T01:17:15.007Z"}