wasmerio/wasmer · error

ExternRef is not yet supported in wasm_c_api

Error message

ExternRef is not yet supported in wasm_c_api

What it means

ExternRef (a host value passed into WebAssembly as an opaque reference) is not implemented in the wasm_c_api-compatible backend this build uses. The method is compiled in to satisfy the common ExternRef API surface, but panics with unimplemented!() whenever called. It signals a feature gap, not a runtime fault in your code.

Source

Thrown at lib/api/src/backend/v8/entities/external.rs:25

#[derive(Debug, Clone)]
#[repr(transparent)]
/// A WebAssembly `extern ref` in the `v8` runtime.
pub struct ExternRef;

impl ExternRef {
    pub fn new<T>(_store: &mut impl AsStoreMut, _value: T) -> Self
    where
        T: Any + Send + Sync + 'static + Sized,
    {
        unimplemented!("ExternRef is not yet supported with wasm_c_api");
    }

    pub fn downcast<'a, T>(&self, _store: &'a impl AsStoreRef) -> Option<&'a T>
    where
        T: Any + Send + Sync + 'static + Sized,
    {
        unimplemented!("ExternRef is not yet supported in wasm_c_api");
    }

    pub(crate) fn vm_externref(&self) -> VMExternRef {
        unimplemented!("ExternRef is not yet supported in wasm_c_api");
    }

    pub(crate) unsafe fn from_vm_externref(
        _store: &mut impl AsStoreMut,
        _vm_externref: VMExternRef,
    ) -> Self {
        unimplemented!("ExternRef is not yet supported in wasm_c_api");
    }

    pub fn is_from_store(&self, _store: &impl AsStoreRef) -> bool {
        true
    }

    pub fn ptr_eq(&self, _other: &Self) -> bool {

View on GitHub (pinned to 8c4b9ee9d3)

Solutions

  1. Switch to a backend that implements ExternRef (e.g. the sys/LLVM or js backend) via cargo features or engine selection
  2. Refactor the host code to avoid externrefs (pass data via linear memory or imports instead)
  3. Implement downcast for this backend upstream or in a fork before calling it
  4. Guard the call behind a capability check so the code path is never reached on unsupported backends

Example fix

// before
let value = extern_ref.downcast::<MyData>(store).unwrap();
// after
// build with a backend that supports ExternRef, or:
let value = match backend_supports_externref() {
    true => extern_ref.downcast::<MyData>(store).unwrap(),
    false => panic!("externref unsupported on this backend; use sys backend"),
};
Defensive patterns

Strategy: validation

Validate before calling

fn externref_supported(engine: &Engine) -> bool {
    // ExternRef is unimplemented on wasm_c_api/v8-backed builds
    !matches!(engine.target_backend(), Backend::WasmCApi | Backend::V8)
}

Type guard

fn is_externref_capable(engine: &Engine) -> bool {
    matches!(engine.backend(), Backend::Sys | Backend::Js)
}

Try / catch

// unimplemented!() panics rather than returning an Err, so catch it at a boundary
let result = std::panic::catch_unwind(|| extern_ref.downcast::<MyData>(store).cloned());
match result {
    Ok(Some(data)) => use_data(data),
    _ => fallback_without_externref(),
}

Prevention

When it happens

Trigger: Calling ExternRef::downcast::<T>(store) on a build where the v8 backend is selected via wasm_c_api; any code path that tries to recover the host value from an ExternRef in that backend.

Common situations: Running wasmer with the v8/wasm_c_api backend while application code (or a guest ABI shim like WASI or component-model glue) uses externrefs; code that works on the sys/LLVM backend panics after switching backends.

Related errors


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