wasmerio/wasmer · error
not a `sys` backend!
Error message
not a `sys` backend!
What it means
wasm_sys_engine_new_with_config converts a C API engine config into a sys (native Cranelift/LLVM/Singlepass) compiler configuration. It panics when the config's backend is not a `sys`-family backend (e.g. the caller passed a V8, WASMI, or Headless engine config to the sys engine constructor). This is a misuse check: only sys backends can be translated into a sys engine config.
Source
Thrown at lib/c-api/src/wasm_c_api/engine/config/sys.rs:142
}
_ => {
update_last_error("Wasmer has not been compiled with the `llvm` feature.");
return None;
}
}
},
wasmer_backend_t::SINGLEPASS => {
cfg_select! {
feature = "singlepass" => {
Box::<wasmer_compiler_singlepass::Singlepass>::default()
}
_ => {
update_last_error("Wasmer has not been compiled with the `singlepass` feature.");
return None;
}
}
},
_ => panic!("not a `sys` backend!")
};
#[cfg(feature = "middlewares")]
for middleware in config.backend_config.middlewares {
compiler_config.push_middleware(middleware.inner.clone());
}
if sys_config.nan_canonicalization {
compiler_config.canonicalize_nans(true);
}
let inner: Engine = {
let mut builder = EngineBuilder::new(compiler_config);
if let Some(target) = config.backend_config.target {
builder = builder.set_target(Some(target.inner));
}
View on GitHub (pinned to 8c4b9ee9d3)
Solutions
- Ensure the config passed to wasm_sys_engine_new_with_config was created with a sys-family backend (Cranelift, LLVM, Singlepass).
- Use the matching engine constructor: wasm_engine_new_with_config / backend-specific engine constructors for non-sys backends.
- Rebuild Wasmer with the compiler features you configure (e.g. --features singlepass) so the backend variant is recognized before the catch-all.
- Check compiler warnings/logs to confirm which backends your Wasmer build actually supports.
Example fix
// before wasmer_backend_t *backend = wasmer_backend_new( /* V8 config */ ); wasmer_engine_t *engine = wasm_sys_engine_new_with_config(v8_config); // panics // after wasmer_config_t *cfg = wasmer_config_new(); wasmer_config_set_compiler(cfg, WASMER_COMPILER_CRANELIFT); // sys backend wasmer_engine_t *engine = wasm_sys_engine_new_with_config(cfg);
Defensive patterns
Strategy: validation
Validate before calling
// C: verify the config's backend is sys-family before calling
if (!wasmer_config_is_sys_backend(cfg)) {
fprintf(stderr, "config is not a sys backend; use the matching engine ctor\n");
return NULL;
}
wasmer_engine_t *engine = wasm_sys_engine_new_with_config(cfg); Type guard
// Rust-side guard when building configs
fn is_sys_backend(b: BackendKind) -> bool {
matches!(b, BackendKind::Cranelift | BackendKind::LLVM | BackendKind::Singlepass)
} Prevention
- Pair each engine constructor with configs built for the same backend.
- Rebuild Wasmer with all compiler features you configure.
- Log the configured backend before engine creation.
When it happens
Trigger: Calling wasm_sys_engine_new_with_config with a wasmer_engine_config_t whose backend was set to a non-sys kind (V8, headless, etc.), or with a compiler enum variant the current feature set doesn't map (the match falls through to the panic arm).
Common situations: Mixing C API engine constructors with configs built for another backend; building Wasmer without the expected compiler feature (e.g. singlepass) so the config variant reaches the catch-all arm; copy-pasted C code using one backend's engine with another's config.
Related errors
- Unsupported backend kind {v:?}
- unimplemented operator {operator:?}
- wasmer_env_set_memory() is not supported
- Unable to determine the wasmer dir: {e}
- cannot create debug directory: {}
AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01).
Data as JSON: /api/errors/ad7f372fa0a6af88.
Report an issue: GitHub.