{"record":{"id":"8908b943a7314621","repo":"wasmerio/wasmer","slug":"cannot-store-reference-type","errorCode":null,"errorMessage":"Cannot store reference type","messagePattern":"Cannot store reference type","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/wasix/src/syscalls/wasix/closure_prepare.rs","lineNumber":82,"sourceCode":"                memory_index,\n            }),\n            Self::F32 => sink.f32_store(MemArg {\n                offset,\n                align: 0,\n                memory_index,\n            }),\n            Self::F64 => sink.f64_store(MemArg {\n                offset,\n                align: 0,\n                memory_index,\n            }),\n            Self::V128 => sink.v128_store(MemArg {\n                offset,\n                align: 0,\n                memory_index,\n            }),\n            // Not supported in closures\n            Self::Ref(_) => panic!(\"Cannot store reference type\"),\n        };\n    }\n    fn load(&self, sink: &mut InstructionSink<'_>, offset: u64, memory_index: u32) {\n        match self {\n            Self::I32 => sink.i32_load(MemArg {\n                offset,\n                align: 0,\n                memory_index,\n            }),\n            Self::I64 => sink.i64_load(MemArg {\n                offset,\n                align: 0,\n                memory_index,\n            }),\n            Self::F32 => sink.f32_load(MemArg {\n                offset,\n                align: 0,\n                memory_index,","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/wasmerio/wasmer/blob/8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5/lib/wasix/src/syscalls/wasix/closure_prepare.rs#L64-L100","documentation":"`store` on the closure value wrapper emits Wasm store instructions (`i32_store`, `v128_store`, etc.) into the generated closure trampoline via `InstructionSink`. There is no store instruction encoding for reference types in this closure ABI (refs are unsupported in closures), so hitting `Self::Ref(_)` panics.","triggerScenarios":"`closure_prepare` generating a trampoline for a function whose parameters include a reference type, so the store-instruction emitter reaches the `Ref` arm; same failure class when materializing parameter stores for externref/funcref/exceptionref values.","commonSituations":"Dynamically prepared closures over reference-types-proposal functions; codegen pipelines that don't sanitize function types before trampoline generation; guests that were originally written for a runtime whose closure ABI tolerated refs.","solutions":["Restrict closures to scalar-typed parameters/results; adapter-wrap any ref-taking function","Marshal references as i32 handles through a side table before preparing the closure","Add a pre-flight type check that rejects `Type::Ref` signatures before invoking `closure_prepare`","Upgrade or recompile the guest so its closure signatures match the scalar-only closure ABI"],"exampleFix":"// before\nclosure_prepare(ctx, func_idx, &[Type::ExternRef], &[])?;\n// after\nlet handle = side_table.insert(externref_value);\nclosure_prepare(ctx, func_idx, &[Type::I32], &[])?;","handlingStrategy":"validation","validationCode":"// Before generating the trampoline, ensure no ref params/results\nif params.iter().any(|p| matches!(p, ClosureType::Ref(_)))\n    || results.iter().any(|r| matches!(r, ClosureType::Ref(_)))\n{\n    return Err(\"closure trampoline cannot store reference types\".into());\n}","typeGuard":"fn is_storable_closure_value(p: &ClosureType) -> bool {\n    !matches!(p, ClosureType::Ref(_))\n}","tryCatchPattern":"let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| param.store(&mut sink, offset, memory_index)));\nif result.is_err() { /* ref store: marshal via handle table and regenerate the trampoline */ }","preventionTips":["Sanitize function types before trampoline generation","Use i32 handles for references in closure ABIs","Unit-test codegen against ref-typed signatures to fail early","Keep runtime and guest closure ABI definitions in sync"],"tags":["wasix","closures","reference-types","codegen","unsupported-feature"],"backgroundTag":"non-scalar-value-unsupported","analyzedSha":"8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5","analyzedAt":"2026-09-01T23:06:31.009Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}