wasm-bindgen "cannot find function ... in this scope" in CI
By Daniel Zoghalchali·Latchkey
The Rust compiler could not resolve a function the code calls. With wasm-bindgen this usually means an imported JS function is invoked outside its #[wasm_bindgen] extern block, or a feature gating that block is off.
What this error means
A wasm build fails with "error[E0425]: cannot find function alert in this scope" or similar, pointing at a call to a function that should be supplied by JavaScript.
cargo
error[E0425]: cannot find function `alert` in this scope
--> src/lib.rs:10:5
|
10 | alert("hello");
| ^^^^^ not found in this scope
Diagnose it: which runtime is actually on PATH?
Runners ship multiple versions of most runtimes and select one through a version manager. When a setup action and a version file disagree, the resulting error is about your code rather than the version.
Terminal
which -a <runtime>
<runtime> --version
echo "PATH=$PATH" | tr ":" "\n" | head -20
# does a version file in the repo disagree with the workflow?
cat .tool-versions .nvmrc .ruby-version .python-version 2>/dev/null
Common causes
The JS import is not declared in an extern block
wasm-bindgen only creates a binding for functions declared inside #[wasm_bindgen] extern "C" { ... }. Calling one that is not declared leaves the name unresolved.
A cfg or feature hides the extern block
The extern block is behind a feature or cfg that is disabled in the CI build, so the binding is not generated.
How to fix it
Declare the import in a wasm-bindgen extern block
Add the JS function to a #[wasm_bindgen] extern "C" block.
Bring it into scope with use where it is called.
Rebuild for the wasm target.
src/lib.rs
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
}
Enable the feature that gates the block
If the extern block is feature-gated, pass that feature in CI so the binding compiles.
Terminal
cargo build --target wasm32-unknown-unknown --features web
How to prevent it
Declare every JS import inside a #[wasm_bindgen] extern block.
Avoid hiding bindings behind features that CI does not enable.
Compile the wasm target in CI so missing bindings fail fast.
Frequently asked questions
What causes wasm-bindgen "cannot find function ... in this scope" in CI?
There are 2 common causes: the js import is not declared in an extern block and a cfg or feature hides the extern block. wasm-bindgen only creates a binding for functions declared inside #[wasm_bindgen] extern "C" { ...
How do I fix wasm-bindgen "cannot find function ... in this scope" in CI?
There are 2 fixes depending on which cause you have: declare the import in a wasm-bindgen extern block and enable the feature that gates the block. Work through them in order, since the first is the most common.
What does wasm-bindgen "cannot find function ... in this scope" in CI actually mean?
A wasm build fails with "error[E0425]: cannot find function alert in this scope" or similar, pointing at a call to a function that should be supplied by JavaScript.
How do I stop wasm-bindgen "cannot find function ... in this scope" in CI happening again?
Declare every JS import inside a #[wasm_bindgen] extern block. The prevention section lists 3 changes that keep it from recurring.