wasmerio/wasmer · error
Cannot get size of reference type
Error message
Cannot get size of reference type
What it means
`size` on the closure parameter/result value wrapper returns the in-memory byte width of a value so `closure_prepare` can lay out the call frame. Reference types (`Self::Ref(_)`) are explicitly not supported in WASIX closures, and their width is undefined for this ABI, so the code panics with this message.
Source
Thrown at lib/wasix/src/syscalls/wasix/closure_prepare.rs:51
let wasix_type = WasmValueType::try_from(value).map_err(|_| Errno::Inval)?;
match wasix_type {
WasmValueType::I32 => Ok(Self::I32),
WasmValueType::I64 => Ok(Self::I64),
WasmValueType::F32 => Ok(Self::F32),
WasmValueType::F64 => Ok(Self::F64),
WasmValueType::V128 => Ok(Self::V128),
_ => Err(Errno::Inval),
}
}
fn size(&self) -> u64 {
match self {
Self::I32 => 4,
Self::I64 => 8,
Self::F32 => 4,
Self::F64 => 8,
Self::V128 => 16,
// Not supported in closures.
Self::Ref(_) => panic!("Cannot get size of reference type"),
}
}
fn store(&self, sink: &mut InstructionSink<'_>, offset: u64, memory_index: u32) {
match self {
Self::I32 => sink.i32_store(MemArg {
offset,
align: 0,
memory_index,
}),
Self::I64 => sink.i64_store(MemArg {
offset,
align: 0,
memory_index,
}),
Self::F32 => sink.f32_store(MemArg {
offset,
align: 0,
memory_index,View on GitHub (pinned to 8c4b9ee9d3)
Solutions
- Change the closure's function signature to use only scalar types (i32/i64/f32/f64/v128)
- Replace reference arguments with i32 handles into a host or guest side table
- Filter or reject ref-typed signatures when building closure descriptors before calling `closure_prepare`
- Recompile the guest module with reference-types disabled or with a closure ABI that maps refs to indices
Example fix
// before: closure over (externref) -> i32 let types = vec![ClosureType::Ref(RefType::Extern)]; // after: pass an index instead let types = vec![ClosureType::I32];
Defensive patterns
Strategy: validation
Validate before calling
// Before closure_prepare, reject ref-typed signatures
if types.iter().any(|t| matches!(t, ClosureType::Ref(_))) {
return Err("reference types are not supported in closures".into());
} Type guard
fn closure_sig_is_scalar(types: &[ClosureType]) -> bool {
types.iter().all(|t| !matches!(t, ClosureType::Ref(_)))
} Try / catch
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| param.size()));
if result.is_err() { /* ref param detected: remap to an i32 handle and retry */ } Prevention
- Build closure descriptors only from scalar-typed functions
- Replace ref params with i32 side-table handles at codegen time
- Add a CI type scan that flags ref-typed closures
- Compile guests with reference-types disabled for closure-heavy workloads
When it happens
Trigger: Preparing a dynamic closure (`closure_prepare`) whose signature includes a reference-typed parameter or result (externref/funcref/exceptionref), causing the size computation to hit the `Ref` arm.
Common situations: Guest modules compiled with reference-types enabled declaring closures over ref-taking functions; code generators emitting closure descriptors from raw function types without filtering refs; ABI drift where newer module types include refs the runtime closure path doesn't support.
Related errors
- Cannot store reference type
- Cannot write non-scalar value as bytes
- Cannot read non-scalar value from memory
- Cannot load reference type
- Failed to free closure index: {e}
AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01).
Data as JSON: /api/errors/ee2ad784a4f4c19f.
Report an issue: GitHub.