{"record":{"id":"faf76747c639ab63","repo":"wasmerio/wasmer","slug":"exceptionrefs-are-not-yet-supported-in-the-js-func","errorCode":null,"errorMessage":"ExceptionRefs are not yet supported in the JS Function API","messagePattern":"ExceptionRefs are not yet supported in the JS Function API","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/api/src/backend/js/utils/convert.rs","lineNumber":116,"sourceCode":"    type DefinitionType = Type;\n\n    fn as_jsvalue(&self, _store: &impl AsStoreRef) -> JsValue {\n        match self {\n            Self::I32(i) => JsValue::from(*i),\n            Self::I64(i) => JsValue::from(*i),\n            Self::F32(f) => JsValue::from(*f),\n            Self::F64(f) => JsValue::from(*f),\n            Self::V128(v) => JsValue::from(*v),\n            Self::FuncRef(Some(func)) => func.as_js().handle.function.clone().into(),\n            Self::FuncRef(None) => JsValue::null(),\n            Self::ExternRef(Some(reference)) => match &reference.0 {\n                crate::BackendExternRef::Js(reference) => reference.as_js_value(),\n                #[allow(unreachable_patterns)]\n                _ => unreachable!(\"a JS function received an externref from another backend\"),\n            },\n            Self::ExternRef(None) => JsValue::null(),\n            Self::ExceptionRef(_) => {\n                unimplemented!(\"ExceptionRefs are not yet supported in the JS Function API\",)\n            }\n        }\n    }\n\n    fn from_jsvalue(\n        store: &mut impl AsStoreMut,\n        type_: &Self::DefinitionType,\n        value: &JsValue,\n    ) -> Result<Self, JsError> {\n        Ok(js_value_to_wasmer(store, type_, value))\n    }\n}\n\nimpl AsJs for Imports {\n    type DefinitionType = crate::module::Module;\n\n    // Annotation is here to prevent spurious IDE warnings.\n    #[allow(unused_unsafe)]","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/wasmerio/wasmer/blob/8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5/lib/api/src/backend/js/utils/convert.rs#L98-L134","documentation":"`as_jsvalue` turns a wasmer `Value` into a `JsValue` for the JS backend. ExceptionRef values have no JS representation in this backend yet, so the match arm calls `unimplemented!` and panics.","triggerScenarios":"Converting any `Value::ExceptionRef(_)` (or `Value::ExceptionRef` in a value list) to a JsValue — e.g. when passing exception-tag payloads or results through the JS function API on the js backend.","commonSituations":"Exception-handling experiments that attach exceptionref payloads; shared code paths that work on native runtimes but hit the stub in the browser.","solutions":["Do not store/transfer ExceptionRef values on the js backend; keep payloads as numeric or externref values","Handle exceptions only at the host boundary and never round-trip ExceptionRef through JS","Use a native backend with exception-handling support if exceptionrefs are required"],"exampleFix":"// before\nValue::ExceptionRef(e) // passed to JS -> panics\n// after\nValue::I32(e.as_i32_handle()) // serialize payload to an integer","handlingStrategy":"type-guard","validationCode":"fn js_convertible(v: &Value) -> bool {\n    !matches!(v, Value::ExceptionRef(_))\n}","typeGuard":"fn js_convertible(v: &Value) -> bool {\n    !matches!(v, Value::ExceptionRef(_))\n}","tryCatchPattern":"if let Value::ExceptionRef(_) = v {\n    return Err(anyhow!(\"ExceptionRef cannot cross the JS boundary\"));\n}","preventionTips":["Never route ExceptionRef values through JS APIs on the js backend","Serialize exception payloads to numeric types before crossing the boundary","Keep exception handling host-side or move to a supporting backend"],"tags":["wasm","javascript-backend","exceptionref","unimplemented"],"backgroundTag":"unimplemented-js-backend-feature","analyzedSha":"8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5","analyzedAt":"2026-09-01T23:06:31.009Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}