Skip to content

mcp__ruvector__hooks_route_enhanced: spawnSync ETIMEDOUT where direct CLI succeeds in ~500ms (v0.2.25) #463

@ronmikailov

Description

@ronmikailov

Summary

mcp__ruvector__hooks_route_enhanced deterministically fails with spawnSync /bin/sh ETIMEDOUT, while the equivalent direct CLI invocation returns in ~500 ms with valid JSON.

The sibling mcp__ruvector__hooks_route (without _enhanced) works correctly via MCP with the same input shape — so the bug is specific to the _enhanced wrapper, not to the MCP layer in general.

Reproduction

# Direct CLI — works in ~500 ms
$ ruvector hooks route-enhanced "review pull request" \
    --file "/home/user/site360/CLAUDE.md"
ONNX initialization failed, using fallback embeddings
{"success":true,"agent":"documentation-specialist","confidence":0.5,"reason":"default mapping","signals":[],"coverageWeight":null,"complexity":null}

Via MCP from Claude Code (any client speaking MCP to the bundled ruvector server):

// Request
{ "tool": "mcp__ruvector__hooks_route_enhanced",
  "params": { "task": "review pull request", "file": "/home/user/site360/CLAUDE.md" } }

// Response
{ "success": false, "error": "spawnSync /bin/sh ETIMEDOUT" }

The error reproduces deterministically across:

  • Different task strings (short and long).
  • Real file paths AND non-existent file paths.
  • Multiple back-to-back MCP server reconnects (/mcp reload in Claude Code).

The sibling mcp__ruvector__hooks_route (same input shape) returns:

{ "success": true, "agent": "documentation-specialist", "confidence": 0.5,
  "reason": "default mapping", "alternates": [], "sonaPatterns": 0, "engineRouted": true }

…in <1 s. So the divergence is in the _enhanced code path.

Hypothesis

spawnSync /bin/sh ETIMEDOUT strongly suggests the MCP server is wrapping the underlying analyzer with child_process.spawnSync(..., { timeout: N }) and either:

  1. The _enhanced path eagerly initializes AST + coverage + diff analyzers and exceeds the configured timeout, even though the same operation completes in <1 s when invoked directly from the parent shell — perhaps because the MCP server's child shell has a different working directory / env that re-runs an initialization step (ruvector hooks init, etc.).
  2. The _enhanced path has a deadlock against a resource that hooks_route doesn't touch (e.g., a lock file in the intelligence store).

Suggested debug steps

  • Diff the spawn invocation between mcp__ruvector__hooks_route (works) and mcp__ruvector__hooks_route_enhanced (hangs). The two MCP tool definitions appear adjacent in the server registration.
  • Increase the spawnSync timeout option in the _enhanced path (or remove it) and re-run; if it then returns successfully, the fix is to bump the timeout to cover AST/coverage warm-up.
  • Confirm whether the MCP server passes the same cwd and env to the child shell that the parent process uses; if not, the child may be initializing pi-brain or another component from scratch on each call.

Environment

  • ruvector: 0.2.25 (which ruvector/home/user/.nvm/versions/node/v20.19.6/bin/ruvector)
  • Node: v20.19.6
  • OS: Linux WSL2 (Ubuntu) on Windows 11
  • Same machine: mcp__ruvector__hooks_route works → CLI itself works → bug is in the _enhanced MCP wrapper specifically.

Workaround for callers (until fixed)

Use the unenhanced mcp__ruvector__hooks_route (loses AST/coverage/diff signals[] enrichment), or shell out to ruvector hooks route-enhanced "<task>" --file <file> and parse the JSON yourself.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions