t8y2/dbx · error · Error

DBX MCP process is not available

Error message

DBX MCP process is not available

What it means

send() throws when the bridge is marked closed or the child MCP process's stdin is no longer writable, i.e. the subprocess has exited or its pipes are broken. Any request/send attempted afterwards fails immediately instead of hanging.

Source

Thrown at crates/dbx-core/assets/pi-mcp-bridge.mjs:111

      message = JSON.parse(line);
    } catch {
      return;
    }
    if (message.id == null) return;
    const request = pending.get(String(message.id));
    if (!request) return;
    pending.delete(String(message.id));
    clearTimeout(request.timer);
    if (message.error) {
      request.reject(new Error(message.error.message ?? JSON.stringify(message.error)));
    } else {
      request.resolve(message.result);
    }
  });

  const send = (message) => {
    if (closed || !child.stdin.writable) {
      throw new Error("DBX MCP process is not available");
    }
    child.stdin.write(`${JSON.stringify(message)}\n`);
  };

  const request = (method, params = {}, signal) =>
    new Promise((resolve, reject) => {
      const id = String(nextId++);
      let onAbort;
      const cleanup = () => {
        clearTimeout(timer);
        if (signal && onAbort) signal.removeEventListener("abort", onAbort);
      };
      const resolveRequest = (value) => {
        cleanup();
        resolve(value);
      };
      const rejectRequest = (error) => {
        cleanup();

View on GitHub (pinned to c0390bff16)

Solutions

  1. Check the child's stderr for the actual crash cause and fix the MCP server startup (program path, args, dependencies)
  2. Recreate/restart the bridge (respawn child) before sending further messages
  3. Serialize calls behind the readiness signal; don't send before the ready file appears and don't reuse the bridge after 'closed'

Example fix

// before
await bridge.request("tools/call", params); // child already exited
// after
if (!bridge.isAlive()) await restartBridge();
await bridge.request("tools/call", params);
Defensive patterns

Strategy: try-catch

Validate before calling

function canSend() {
  return !closed && child && child.stdin && child.stdin.writable;
}
if (!canSend()) await restartBridge();

Type guard

function isBridgeAlive(bridge) {
  return bridge && !bridge.closed && bridge.child?.stdin?.writable === true;
}

Try / catch

try {
  await request('tools/call', params, signal);
} catch (e) {
  if (e.message === 'DBX MCP process is not available') {
    await respawnChild(); // inspect child stderr for crash cause
    return retryOnce();
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling request()/send() after the child process exited (crash, non-zero exit, killed); racing startup before stdin is writable; a tool call issued after the readiness/closed lifecycle ended.

Common situations: MCP server crashed on startup (bad args, missing module); child killed by OOM or signal; tool invoked after teardown; slow startup with caller racing the ready file.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/efb2a1b6c4cd8570. Report an issue: GitHub.