zeroclaw-labs/zeroclaw · error · anyhow::Error
WASM module {} is {} MB — exceeds 50 MB safety limit
Error message
WASM module {} is {} MB — exceeds 50 MB safety limit What it means
After reading the module bytes, execute_module enforces a 50 MB sanity limit on the file size before compiling. Modules anywhere near this size are almost always the wrong artifact — a debug build with DWARF, a bundle with embedded assets, or a non-WASM binary dropped in the tools dir — and compiling them wastes the memory budget guarded by memory_limit_mb.
Source
Thrown at crates/zeroclaw-runtime/src/platform/wasm.rs:148
// Resolve module path
let tools_path = self.tools_dir(workspace_dir);
let module_path = tools_path.join(format!("{module_name}.wasm"));
if !module_path.exists() {
bail!(
"WASM module not found: {} (looked in {})",
module_name,
tools_path.display()
);
}
// Read module bytes
let wasm_bytes = std::fs::read(&module_path)
.with_context(|| format!("Failed to read WASM module: {}", module_path.display().to_string()))?;
// Validate module size (sanity check)
if wasm_bytes.len() > 50 * 1024 * 1024 {
bail!(
"WASM module {} is {} MB — exceeds 50 MB safety limit",
module_name,
wasm_bytes.len() / (1024 * 1024)
);
}
// Configure engine with fuel metering
let mut engine_config = wasmi::Config::default();
engine_config.consume_fuel(true);
let engine = Engine::new(&engine_config);
// Parse and validate module
let module = Module::new(&engine, &wasm_bytes[..])
.with_context(|| format!("Failed to parse WASM module: {module_name}"))?;
// Create store with fuel budget
let mut store = Store::new(&engine, ());
let fuel = self.effective_fuel(caps);View on GitHub (pinned to 88bb9c8533)
Solutions
- Strip and optimize: wasm-opt -Oz module.wasm -o module.wasm and/or wasm-strip module.wasm
- Move large embedded assets out of the module and load them at runtime from the workspace
- Verify the file is actually a WASM module (file module.wasm, or wasm-objdump -h) — not a native ELF or a .map file
- If a legitimate module truly exceeds 50 MB, split it into smaller modules; the limit is a hard safety cap
Example fix
# before: 80 MB debug build cp target/wasm32-*/debug/tool.wasm tools/wasm/tool.wasm # after: ~2 MB release build, stripped cp target/wasm32-*/release/tool.wasm tools/wasm/tool.wasm wasm-opt -Oz tools/wasm/tool.wasm -o tools/wasm/tool.wasm wasm-strip tools/wasm/tool.wasm
Defensive patterns
Strategy: validation
Validate before calling
const MAX_MODULE_BYTES: u64 = 50 * 1024 * 1024;
let meta = std::fs::metadata(&module_path)?;
if meta.len() > MAX_MODULE_BYTES {
// reject early: likely wrong artifact (debug build / non-wasm file)
} Try / catch
Err(e) if e.to_string().contains("exceeds 50 MB safety limit") => {
// fix the artifact: wasm-opt -Oz + wasm-strip, or remove embedded assets; do not raise the limit
} Prevention
- Ship only optimized, stripped release wasm builds; make stripping a CI step
- Check the wasm magic bytes (\0asm) and size in a pre-deploy lint
- Keep assets outside modules and load at runtime
When it happens
Trigger: Placing an unstripped debug wasm build (with debug info) in the tools dir; embedding large assets (models, datasets) into the module at build time; accidentally pointing module_name at a large native binary or source map; compressed vs uncompressed mixups doubling size.
Common situations: Teams shipping dev builds to production; asset-heavy tools that inline data at compile time; CI artifacts that include debug sections by default.
Related errors
- runtime.wasm.memory_limit_mb must be > 0
- runtime.wasm.memory_limit_mb of {} exceeds the 4 GB safety l
- knowledge graph node limit reached ({}/{})
- grok_cli max_acp_stdout_bytes must be between {} and {} byte
- runtime.wasm.tools_dir cannot be empty
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/2bbaea1aa3cd8225.
Report an issue: GitHub.