decolua/9router · error

Bridge not running: ${name}

Error message

Bridge not running: ${name}

What it means

sendToChild writes a JSON-RPC message to a spawned stdio bridge child's stdin. It throws if no live entry with a writable stdin exists for that name — i.e. the child process died, was never spawned, or was just cleaned up.

Source

Thrown at src/lib/mcp/stdioSseBridge.js:174

  // No sessions left → kill child to avoid idle orphan process leak.
  if (entry.sessions.size === 0) {
    try { entry.proc.kill(); } catch { /* ignore */ }
    getStore().delete(name);
  }
}

// Kill all spawned MCP children — called on app shutdown to prevent orphans.
function killAllBridges() {
  const store = getStore();
  for (const [name, entry] of store) {
    try { entry.proc.kill(); } catch { /* ignore */ }
    store.delete(name);
  }
}

function sendToChild(name, jsonRpc) {
  const entry = getStore().get(name);
  if (!entry?.proc?.stdin?.writable) throw new Error(`Bridge not running: ${name}`);
  entry.proc.stdin.write(`${JSON.stringify(jsonRpc)}\n`);
}

function isRunning(name) {
  const entry = getStore().get(name);
  return !!(entry?.proc && !entry.proc.killed && entry.proc.exitCode === null);
}

module.exports = { getOrSpawn, registerSession, unregisterSession, sendToChild, isRunning, findPlugin, killAllBridges };

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Re-issue the request: entry() getOrSpawn will respawn a dead child automatically if the plugin is registered.
  2. Check the child's stderr/logs for why the process died (missing binary, npx network failure, crash) and fix the root cause.
  3. Verify the plugin command runs standalone (e.g. `npx -y <pkg> --help`) — a bad command or missing dependency makes the child exit immediately.
  4. Treat the error as a stale session on the client side: re-initialize the MCP session to get a fresh bridge.

Example fix

null
Defensive patterns

Strategy: try-catch

Validate before calling

import { isRunning } from "@/lib/mcp/stdioSseBridge"; // or equivalent check
if (!isRunning(name)) {
  getOrSpawn(name); // respawn before sending
}
sendToChild(name, jsonRpc);

Try / catch

try {
  sendToChild(name, jsonRpc);
} catch (err) {
  if (err.message.startsWith("Bridge not running:")) {
    getOrSpawn(name);        // respawn the dead child
    sendToChild(name, jsonRpc); // retry once
  } else throw err;
}

Prevention

When it happens

Trigger: POSTing a JSON-RPC message to the bridge after the plugin process exited (crash, was killed, command failed to launch), or sending to a name that was never getOrSpawn'ed, or racing a cleanup that deleted the store entry.

Common situations: MCP server binary crashed mid-session (e.g. npx failed, OOM-killed child); session idle timeout reaped the child while the client still holds it; sending the very first request without an initialize that would have spawned the process.

Related errors


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/5a0fdc1a6bdf08bb. Report an issue: GitHub.