ruvnet/ruflo · error · Error

MCP initialization failed: ${initResponse.error.message}

Error message

MCP initialization failed: ${initResponse.error.message}

What it means

Thrown by initWasmMcp() after the WASM module loaded and a WasmMcpServer was constructed, when the JSON-RPC "initialize" call (protocolVersion 2024-11-05, clientInfo ruvocal-ui) returns an error object. The thrown message forwards initResponse.error.message so the underlying server-side reason is visible.

Source

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

	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);

		// Check for persisted active template
		const savedTemplateId = await idb.getSetting<string>("activeTemplateId");
		let templateName: string | null = null;

		if (savedTemplateId) {
			try {
				const template = gallery.get(savedTemplateId);
				gallery.setActive(savedTemplateId);
				templateName = template.name;
			} catch {
				// Template not found, ignore
			}
		}

View on GitHub (pinned to 6b01dc5a68)

Solutions

  1. Read initResponse.error.message in the error text — it names the exact rejection reason.
  2. Confirm protocolVersion "2024-11-05" matches what the WASM binary was built against.
  3. Clear IndexedDB wasm-mcp state (syncFromIndexedDB runs right after init and can re-trigger older-shape data) and retry.
  4. Rebuild and redeploy the WASM package so glue and binary are from the same commit.
  5. If the error is transient (memory pressure in the worker), expose a retry around initWasmMcp with one re-load attempt.

Example fix

// before
if (initResponse.error) throw new Error(`MCP initialization failed: ${initResponse.error.message}`);
// after
if (initResponse.error) {
  throw new Error(`MCP initialization failed: ${initResponse.error.message} (code=${initResponse.error.code ?? "?"})`,);
}
Defensive patterns

Strategy: try-catch

Validate before calling

const PROTOCOL = "2024-11-05";
function validClientInfo(ci: unknown): ci is { name: string; version: string } {
  return !!ci && typeof (ci as { name: string }).name === "string" && typeof (ci as { version: string }).version === "string";
}
const clientInfo = { name: "ruvocal-ui", version: "1.0.0" };
if (!validClientInfo(clientInfo)) throw new Error("clientInfo missing name/version");

Type guard

interface McpError { code?: number; message?: string; data?: unknown }
function isMcpError(r: unknown): r is { error: McpError } {
  return typeof r === "object" && r !== null && "error" in (r as object);
}

Try / catch

try {
  await initWasmMcp();
} catch (e) {
  const msg = String((e as Error)?.message ?? e);
  if (msg.startsWith("MCP initialization failed")) {
    // often a version skew — clear persisted state and retry once
    await clearWasmIndexedDB();
    await initWasmMcp();
  } else throw e;
}

Prevention

When it happens

Trigger: The WASM MCP server rejects the initialize handshake: unsupported protocolVersion, missing required clientInfo fields, an internal server exception during init, or a version skew between the glue JS and the compiled WASM binary.

Common situations: Upgraded only the JS glue but not the .wasm (or vice versa) so protocolVersion expectations diverge; the WASM build was compiled with a different MCP protocol version; a persisted IndexedDB state from an older version causes init to fail on reload.

Related errors


AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12). Data as JSON: /api/errors/88ccb184d3977dcd. Report an issue: GitHub.