wasmerio/wasmer · error

The {val:?} is not yet supported

Error message

The {val:?} is not yet supported

What it means

`get_table_item` on the JS backend converts the stored table element back into a wasmer Value. Only externref-backed JS references are implemented; any other element representation (e.g. funcref or a non-JS backend externref) hits the `unimplemented!` arm and panics.

Source

Thrown at lib/api/src/backend/js/entities/table.rs:39

        .set_raw(item_index, item)
        .map_err(|e| e.into())
}

fn get_table_item(store: &mut impl AsStoreMut, val: Value) -> Result<JsValue, RuntimeError> {
    if !val.is_from_store(store) {
        return Err(RuntimeError::new("cannot pass Value across contexts"));
    }
    match val {
        Value::FuncRef(Some(ref func)) => Ok(func.as_js().handle.function.clone().into_inner().into()),
        Value::FuncRef(None) | Value::ExternRef(None) => Ok(JsValue::null()),
        Value::ExternRef(Some(ref reference)) => match &reference.0 {
            crate::BackendExternRef::Js(reference) => Ok(reference.as_js_value()),
            #[allow(unreachable_patterns)]
            _ => Err(RuntimeError::new(
                "cannot pass an externref across backends",
            )),
        },
        _ => unimplemented!("The {val:?} is not yet supported"),
    }
}

impl Table {
    pub fn new(
        store: &mut impl AsStoreMut,
        ty: TableType,
        init: Value,
    ) -> Result<Self, RuntimeError> {
        let mut store = store;
        let descriptor = js_sys::Object::new();
        js_sys::Reflect::set(&descriptor, &"initial".into(), &ty.minimum.into())?;
        if let Some(max) = ty.maximum {
            js_sys::Reflect::set(&descriptor, &"maximum".into(), &max.into())?;
        }
        let element = match ty.ty {
            Type::FuncRef => "anyfunc",
            Type::ExternRef => "externref",

View on GitHub (pinned to 8c4b9ee9d3)

Solutions

  1. Only read items from JS-backend tables with element type `externref` holding JS-originated values
  2. Handle funcref tables through `Function::new`/JS function wrappers instead of raw `get`
  3. Gate table item access behind a backend check and provide a stub for unsupported element types

Example fix

// before
let val = table.get(&mut store, index)?; // funcref table
// after
if table.ty(&store).element != Type::ExternRef {
    return Err(RuntimeError::new("unsupported table element type on js backend"));
}
let val = table.get(&mut store, index)?;
Defensive patterns

Strategy: validation

Validate before calling

fn table_items_supported(table: &Table, store: &impl AsStoreRef) -> bool {
    table.ty(store).element == Type::ExternRef
}

Try / catch

// stub panics, not Result: check element type before get/set/grow
if !table_items_supported(&table, &store) {
    return Err(anyhow!("js backend only supports externref table items"));
}

Prevention

When it happens

Trigger: Calling `Table::get`/`set`/`grow` (via `new`/`set`/`grow` -> `get_table_item`) on a JS-backend table whose element type or stored value is not a JS-backed externref — e.g. funcref tables or externrefs created by a non-JS backend.

Common situations: Cross-backend code moving tables/externrefs between sys and js runtimes; creating tables with `TableType` element types other than externref and then reading items from the browser build.

Related errors


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