apache/shenyu · error · ShenyuWasmInitException
Can't find wasm file
Error message
Can't find wasm file: ${wasmName} What it means
WasmLoader locates the '.wasm' binary as a classpath resource named after the fully-qualified class name (ClassName + '.wasm') via clazz.getClassLoader().getResource(). If no such resource is on the classpath it throws ShenyuWasmInitException at construction time, because the WebAssembly module cannot be instantiated at all.
Solutions
- Ensure the .wasm file lives under src/main/resources with a path matching the Java class's package and the exact class simple name, e.g. org/apache/shenyu/plugin/xxx/MyPlugin.wasm for class org.apache.shenyu.plugin.xxx.MyPlugin.
- Rebuild the module so the .wasm is copied into target/classes and packaged into the jar.
- Check Maven build config (resource excludes/filtering) is not stripping .wasm files; add them to <resources> if needed.
- If you renamed the class, rename the .wasm file (or pass the correct wasmClass reference) to keep them in sync.
Example fix
// before: class org.apache.shenyu.plugin.ai.FooPlugin, resource at resources/foo.wasm // after src/main/resources/org/apache/shenyu/plugin/ai/FooPlugin.wasm
Defensive patterns
Strategy: validation
Validate before calling
String resource = MyClass.class.getName().replace('.', '/') + ".wasm";
if (MyClass.class.getClassLoader().getResource(resource) == null) {
throw new IllegalStateException("wasm resource missing from classpath: " + resource);
} Try / catch
try {
WasmLoader loader = new MyWasmPlugin();
} catch (ShenyuWasmInitException e) {
if (e.getMessage().startsWith("Can't find wasm file")) { /* fix packaging/renaming */ }
throw e;
} Prevention
- Keep the .wasm file name and package path in lockstep with the Java class name; rename both together.
- Check the packaged jar (jar tf) for the .wasm entry in CI.
- Avoid Maven resource excludes/filtering on *.wasm.
When it happens
Trigger: Constructing a WasmLoader (or subclass plugin) when the .wasm file was not packaged next to the class: the file name does not equal the fully-qualified class name + '.wasm', or the resource was excluded from the jar/target classes.
Common situations: Renaming a Java class without renaming the accompanying .wasm file (or vice versa); Maven resource filtering/excludes dropping .wasm files from the jar; building a custom plugin and forgetting to place the compiled .wasm under src/main/resources with the matching package path.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- memory not available in wasm file
- namespace is not exist
- when binding discovery don't find selector
- shenyu this discovery is not found in current namespace
- The task queue does not have executor!
AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12).
Data as JSON: /api/errors/3c2905bf425186f9.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-plugin/shenyu-plugin-wasm-api/src/main/java/org/apache/shenyu/plugin/wasm/api/loader/WasmLoader.java:90
* <ol>
* <li>Register full WASI preview1 functions via Chicory's built-in implementation</li>
* <li>If {@code initializer} is non-null, call it; otherwise register built-in host functions
* ({@code get_args}/{@code put_result}) and call {@link #initWasmCallJavaFunc(Store)}</li>
* </ol>
*
* @param wasmClass the class whose name determines the .wasm resource path; if null, uses
* {@code this.getClass()} (inheritance mode)
* @param initializer optional consumer to register host functions; when non-null the built-in
* host functions and {@link #initWasmCallJavaFunc(Store)} are skipped
*/
public WasmLoader(final Class<?> wasmClass, final Consumer<Store> initializer) {
final Class<?> clazz = Objects.nonNull(wasmClass) ? wasmClass : this.getClass();
this.wasmName = clazz.getName() + ".wasm";
try {
// locate `.wasm` lib.
URL resource = clazz.getClassLoader().getResource(wasmName);
if (Objects.isNull(resource)) {
throw new ShenyuWasmInitException("Can't find wasm file: " + wasmName);
}
// Instantiates the WebAssembly module.
this.store = new Store();
// Register WASI preview1 functions via Chicory's built-in implementation,
// then override proc_exit with a no-op to avoid WasiExitException.
registerWasiStubs(store);
// Allow subclasses to register custom host functions (get_args/put_result).
if (Objects.nonNull(initializer)) {
initializer.accept(store);
} else {
registerBuiltinHostFunctions(store);
}
// Allow WasmLoader subclasses to override and register additional host functions.
// Only called when not using Consumer initializer, to avoid double invocation.View on GitHub (pinned to 567142e072)