Skip to content

MCP integration tests fail on Node ≥25 dev machines (spawned servers blocked by version check) #478

@eddieran

Description

@eddieran

Symptom

On a developer machine running Node.js 25 or later, npm test against main reports:

Test Files  4 failed | 44 passed (48)
     Tests  13 failed | 1019 passed | 2 skipped (1034)

All 13 failures are in subprocess-based MCP integration tests:

File Failing tests
__tests__/mcp-daemon.test.ts 7
__tests__/mcp-initialize.test.ts 2
__tests__/mcp-ppid-watchdog.test.ts 1
__tests__/mcp-roots.test.ts 3

The failure mode is always the same: every assertion that waits for an MCP message from the spawned child times out with Timed out. Messages so far: []. The PPID-watchdog test instead fails with expected false to be true (the kill(pid, 0) probe never sees the child exit because the child died on startup, not on SIGKILL).

Root cause

src/bin/codegraph.ts:65–71 hard-blocks the CLI when nodeMajor >= 25:

if (nodeMajor >= 25) {
  process.stderr.write(buildNode25BlockBanner(nodeVersion) + '\n');
  if (!process.env.CODEGRAPH_ALLOW_UNSAFE_NODE) {
    process.exit(1);
  }
}

Each affected test spawns node dist/bin/codegraph.js serve --mcp … with the test process's own Node binary (process.execPath). On Node ≥25, that child writes the unsupported-version banner and exits before the test sends initialize, so every subsequent waitForMessage times out.

The block exists for good reason (Node 25's V8 turboshaft WASM JIT Zone allocator bug, issue #81), but the test scenarios — short-lived servers, no production indexing — won't hit the OOM the block protects against. The CLI itself should still enforce the block for end users.

Confirmed fix

Setting CODEGRAPH_ALLOW_UNSAFE_NODE=1 in the environment vitest inherits makes all 13 tests pass on Node 26.x:

$ CODEGRAPH_ALLOW_UNSAFE_NODE=1 npx vitest run __tests__/mcp-roots.test.ts
 Test Files  1 passed (1)
      Tests  3 passed (3)
$ CODEGRAPH_ALLOW_UNSAFE_NODE=1 npx vitest run __tests__/mcp-ppid-watchdog.test.ts
 Test Files  1 passed (1)
      Tests  1 passed (1)

Since each spawning test already builds its child env via { ...process.env, ... } (or inherits process.env when no env is passed), setting the variable once in vitest.config.ts propagates it to every spawned subprocess without modifying any individual test file.

Impact

  • CI on Node 22/23 is unaffected (the block only fires on ≥25).
  • New contributors on a recent macOS/Linux box (Node 25+ shipped via Homebrew / nvm latest) currently get a noisy npm test baseline and have to discover the env-var workaround to verify their changes. The note in CLAUDE.md about pre-existing Windows failures doesn't mention this macOS/Linux case, so the failures look unrelated to the underlying Node version.

Proposed fix

Set CODEGRAPH_ALLOW_UNSAFE_NODE=1 via vitest.config.ts's test.env so it propagates into every spawned subprocess and the suite is green on any supported (or newer) Node. PR to follow.

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