ruvnet/ruflo · error

Failed to load WASM module

Error message

Failed to load WASM module

What it means

Thrown by initWasmMcp() when loadWasm() resolves to null. The browser-side MCP server is implemented as a WASM module (WasmMcpServer, WasmGallery); if the module cannot be fetched or instantiated, loadWasm swallows the cause and returns null, and this error surfaces instead. initWasmMcp guards with a loading flag, so concurrent calls don't retry — the failed state sticks until a fresh call after error reset.

Solutions

  1. Open the browser DevTools Network tab, reload, and find the failing .wasm request (status 404/403 or CSP console error).
  2. 404: redeploy so built assets and their hashes are consistent; verify the `base` path configuration matches the hosting prefix.
  3. CSP: add 'wasm-unsafe-eval' to the script-src directive (and allow the asset origin).
  4. Hard-refresh / unregister the service worker to clear stale asset references.
  5. Confirm WebAssembly availability: typeof WebAssembly === 'object' in the console.

Example fix

# CSP header (before)
Content-Security-Policy: script-src 'self'

# CSP header (after)
Content-Security-Policy: script-src 'self' 'wasm-unsafe-eval'
Defensive patterns

Strategy: try-catch

Validate before calling

if (typeof WebAssembly === "undefined") {
	throw new Error("WebAssembly unavailable in this browser");
}

Type guard

function supportsWasm(): boolean {
	try {
		return typeof WebAssembly?.instantiate === "function";
	} catch {
		return false;
	}
}

Try / catch

try {
	const ok = await initWasmMcp();
	if (!ok) disableMcpUi();
} catch (err) {
	// state.error is set; show a retry button rather than leaving loading=true
	showWasmErrorAndRetry(String(err));
}

Prevention

When it happens

Trigger: The WASM binary or its JS glue fails to load in the browser: 404 on the asset after a partial deploy or wrong `base` path, CSP blocking wasm-unsafe-eval, OutOfMemory during instantiation, or a browser with WebAssembly disabled/unsupported.

Common situations: Deploying under a sub-path where asset URLs for the .wasm file are wrong; strict Content-Security-Policy headers on the hosting layer; stale service worker serving an old HTML with new asset hashes; very old mobile browsers.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/53ff35dcb3707336. Report an issue: GitHub.

Appendix: source

Thrown at ruflo/src/ruvocal/src/lib/stores/wasmMcp.ts:84

// Request ID counter
let requestId = 0;

/**
 * Initialize the WASM MCP server
 */
export async function initWasmMcp(): Promise<boolean> {
	if (!browser) return false;

	const state = get(wasmMcpState);
	if (state.loaded || state.loading) return state.loaded;

	wasmMcpState.update((s) => ({ ...s, loading: true, error: null }));

	try {
		// Load WASM module
		const wasm = await loadWasm();
		if (!wasm) {
			throw new Error("Failed to load WASM module");
		}

		// Create MCP server and gallery instances
		const mcpServer = new wasm.WasmMcpServer();
		const gallery = new wasm.WasmGallery();

		// Initialize the MCP server
		const initResponse = callMcpInternal(mcpServer, "initialize", {
			protocolVersion: "2024-11-05",
			clientInfo: { name: "ruvocal-ui", version: "1.0.0" },
		});

		if (initResponse.error) {
			throw new Error(`MCP initialization failed: ${initResponse.error.message}`);
		}

		// Load persisted filesystem state from IndexedDB
		await syncFromIndexedDB(mcpServer);

View on GitHub (pinned to fa13ee4ad6)