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.

Solutions

  1. Change the closure's function signature to use only scalar types (i32/i64/f32/f64/v128)
  2. Replace reference arguments with i32 handles into a host or guest side table
  3. Filter or reject ref-typed signatures when building closure descriptors before calling `closure_prepare`
  4. 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

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


AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01). Data as JSON: /api/errors/ee2ad784a4f4c19f. Report an issue: GitHub.

Appendix: 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)