Repository navigation
Description
On Windows, bun run test fails 24 tests across 7 files. Every one of them fails after its assertions have passed, in fs.rmSync on the temp project:
× Resolution Module > PHP Include Resolution > resolves require_once to a file→file imports edge (#660)
→ EPERM, Permission denied: \?\C:\Users\…\Temp\codegraph-php-e2e-zmZ4mt
❯ __tests__/resolution.test.ts:3792 fs.rmSync(tempProject, { recursive: true, force: true });
Windows refuses to remove a directory that holds an open file; POSIX unlinks one happily, which is why CI does not see this. The tests are not wrong about the graph — they are wrong about the cleanup.
Two causes
1. The graph is never closed. __tests__/arkts-resolution.test.ts calls CodeGraph.initSync 7 times and close() zero times; frameworks-integration.test.ts closes in two JVM tests and not in the other three; resolution.test.ts's C++/PHP end-to-end tests additionally open a second DatabaseConnection for a raw edge query and never close that either. The SQLite handle is still open when rmSync runs. 14 tests.
2. A killed child still holds its handles. The four mcp-* suites do close the graph and do child.kill('SIGKILL') — then call rmSync synchronously in the same tick. A signalled process has not exited yet. 10 tests.
Measured, both arms, same file and command back to back: adding cg.close() to arkts-resolution.test.ts's ohpm main entry test makes it pass; removing that one line makes it fail with EPERM again.
Affected
| Tests | File | Cause |
|---|---|---|
| 7 | arkts-resolution.test.ts |
unclosed graph |
| 4 | resolution.test.ts (C++/PHP e2e) |
unclosed graph + unclosed DatabaseConnection |
| 3 | frameworks-integration.test.ts (JVM FQN imports) |
unclosed graph |
| 3 | mcp-initialize.test.ts |
killed child not awaited |
| 3 | mcp-roots.test.ts |
killed child not awaited |
| 3 | mcp-subproject-adoption.test.ts |
killed child not awaited |
| 1 | mcp-daemon.test.ts |
killed child not awaited (fixed 50ms grace period) |
Awaiting the tracked child is necessary but not sufficient for the MCP suites: with only that, a full-suite run still failed 2 of 4,240 — a different pair each time — because the server can leave a detached daemon the suite never tracks, and mcp-daemon's concurrent-launcher test deliberately leaves one alive.
Environment
Windows 11, Node 22, vitest run from a built tree (tsc + assets + ui workspace). Before: 3,975 passing / 24 failing / 234 skipped. Not reproduced on Linux — the guess is that nobody outside a Windows host ever sees it, and the failure is pure teardown, so no behaviour of the indexer is implicated.
PR follows.
Activity
bompus commentedon Sep 6, 2026
Duplicate — #1717 already fixes this and predates the issue. Closing in favour of that PR.