Summary
On @colbymchenry/codegraph@1.1.3, Codex MCP still becomes unstable on WSL2 /mnt/d even with the recommended workaround from #974:
[mcp_servers.codegraph]
command = "env"
args = ["CODEGRAPH_NO_DAEMON=1", "codegraph", "serve", "--mcp", "--no-watch"]
The new distinguishing signal is that a single Codex parent process spawned two CodeGraph MCP server processes for the same physical repository with different path casing:
Codex parent:
3608352 .../bin/codex
parent cwd=/mnt/d/02_SoftwareCodes/RCSS.Studio/Tekla/TeklaDrawingHelper_TeklaInternal
CodeGraph MCP children of the same parent:
3608757 cwd=/mnt/d/02_SoftwareCodes/RCSS.Studio/Tekla/TeklaDrawingHelper_TeklaInternal
3609744 cwd=/mnt/d/02_softwarecodes/rcss.studio/tekla/tekladrawinghelper_teklainternal
Both paths point to the same .codegraph/codegraph.db inode on DrvFs:
upper=70:6192449487701361 /mnt/d/02_SoftwareCodes/RCSS.Studio/Tekla/TeklaDrawingHelper_TeklaInternal/.codegraph/codegraph.db
lower=70:6192449487701361 /mnt/d/02_softwarecodes/rcss.studio/tekla/tekladrawinghelper_teklainternal/.codegraph/codegraph.db
After this, CLI codegraph status reported:
Failed to get status: database disk image is malformed
Killing the repo-matching CodeGraph MCP processes made CLI status/sync recover, but the Codex MCP tool call then failed with:
Error: tool call error: tool call failed for `codegraph/codegraph_explore`
Caused by:
Transport closed
Environment
- CodeGraph:
1.1.3
- Node:
v22.19.0
- Client: OpenAI Codex CLI
- OS: WSL2 Ubuntu on Windows, project on
/mnt/d DrvFs
- Project path used by shell / parent process:
/mnt/d/02_SoftwareCodes/RCSS.Studio/Tekla/TeklaDrawingHelper_TeklaInternal
- MCP config:
[mcp_servers.codegraph]
command = "env"
args = ["CODEGRAPH_NO_DAEMON=1", "codegraph", "serve", "--mcp", "--no-watch"]
Observed process state
pwd and pwd -P from the active shell both showed the uppercase canonical-looking path:
/mnt/d/02_SoftwareCodes/RCSS.Studio/Tekla/TeklaDrawingHelper_TeklaInternal
/mnt/d/02_SoftwareCodes/RCSS.Studio/Tekla/TeklaDrawingHelper_TeklaInternal
The Codex parent process also had the uppercase cwd:
3608352 3608345 Mon Jun 29 15:39:36 2026 .../bin/codex
parent cwd=/mnt/d/02_SoftwareCodes/RCSS.Studio/Tekla/TeklaDrawingHelper_TeklaInternal
But the same parent spawned two CodeGraph MCP server processes:
PID 3608757
ppid=3608352
cwd=/mnt/d/02_SoftwareCodes/RCSS.Studio/Tekla/TeklaDrawingHelper_TeklaInternal
env=CODEGRAPH_NO_DAEMON=1
cmdline=node .../bin/codegraph serve --mcp --no-watch
PID 3609744
ppid=3608352
cwd=/mnt/d/02_softwarecodes/rcss.studio/tekla/tekladrawinghelper_teklainternal
env=CODEGRAPH_NO_DAEMON=1
cmdline=node .../bin/codegraph serve --mcp --no-watch
The Codex MCP tool call also carried the lower-case project path:
codegraph.codegraph_explore({
"projectPath": "/mnt/d/02_softwarecodes/rcss.studio/tekla/tekladrawinghelper_teklainternal",
"query": "RunCurrentVersionSwitch CurrentVersionSwitchService ExecuteBatch ValidateBatchPreconditions RecordBatchNotExecuted DrawingTransferManagerForm CanExecuteBatchVersionSwitch DrawingTransferPlanRecord IsExecutableRecord",
"maxFiles": 5
})
Daemon-related observation despite CODEGRAPH_NO_DAEMON=1
Even with CODEGRAPH_NO_DAEMON=1 in the MCP server environment, .codegraph/daemon.pid contained a relocated daemon:
{
"pid": 3607983,
"version": "1.1.3",
"socketPath": "/tmp/codegraph-befc5052950cc73f.sock",
"startedAt": 1782718772179
}
Process:
PID 3607983
cwd=/mnt/d/02_SoftwareCodes/RCSS.Studio/Tekla/TeklaDrawingHelper_TeklaInternal
env=CODEGRAPH_DAEMON_INTERNAL=1
cmdline=.../codegraph.js serve --mcp --path /mnt/d/02_SoftwareCodes/RCSS.Studio/Tekla/TeklaDrawingHelper_TeklaInternal
.codegraph/daemon.log included:
[CodeGraph daemon] Socket /mnt/d/02_SoftwareCodes/RCSS.Studio/Tekla/TeklaDrawingHelper_TeklaInternal/.codegraph/daemon.sock unusable (ENOTSUP); relocating to /tmp/codegraph-befc5052950cc73f.sock.
[CodeGraph daemon] Listening on /tmp/codegraph-befc5052950cc73f.sock (pid 3607983, v1.1.3). Idle timeout 300000ms.
[CodeGraph MCP] File watcher disabled — project is on a WSL2 /mnt/ drive, where recursive fs.watch is too slow to be reliable. The graph will not auto-update; run `codegraph sync` (or install the git sync hooks via `codegraph init`) to refresh.
This may be expected under some path, but it was surprising because the user-facing MCP process had CODEGRAPH_NO_DAEMON=1.
Symptoms
codegraph sync was run.
codegraph status then failed:
Failed to get status: database disk image is malformed
- Multiple CodeGraph MCP processes existed, including two for the same physical repo via upper/lower casing.
- After killing repo-matching processes, CLI
status recovered and sync completed.
- The subsequent Codex MCP call failed:
Error: tool call error: tool call failed for `codegraph/codegraph_explore`
Caused by:
Transport closed
Why this seems distinct from #974
#974 was on v1.1.0 and the recommended workaround was CODEGRAPH_NO_DAEMON=1 to skip the shared daemon on WSL2 /mnt.
In this case:
- CodeGraph is
1.1.3.
- The MCP server process has
CODEGRAPH_NO_DAEMON=1.
- The MCP server also has
--no-watch.
- The same Codex parent process spawns two CodeGraph MCP children for the same physical repo with different path casing.
- The same SQLite database inode is shared by those two path spellings.
- A relocated internal daemon still appears in
.codegraph/daemon.pid.
- The index can become malformed, then CLI recovers after killing repo-matching MCP processes, while MCP still returns
Transport closed.
Expected behavior
On WSL2 /mnt / DrvFs, CodeGraph should either:
- canonicalize/case-fold project roots that point to the same physical directory before deciding project identity and
.codegraph ownership, or
- lock the SQLite database robustly across equivalent path spellings, or
- fail fast with an actionable error when the same physical
.codegraph directory is opened through multiple path spellings.
It should not allow two MCP processes from the same client parent to treat upper/lowercase spellings of the same DrvFs path as separate project roots while writing the same SQLite database.
Questions
- Is
CODEGRAPH_NO_DAEMON=1 expected to fully prevent creation/use of a shared daemon in v1.1.3, or can a relocated CODEGRAPH_DAEMON_INTERNAL=1 process still appear?
- Does CodeGraph currently canonicalize WSL DrvFs paths by physical identity, or only by path string/realpath?
- Would you prefer this be fixed in CodeGraph project-root identity handling, or should MCP clients like Codex avoid sending
projectPath values that differ in casing from the server process cwd?
I can provide additional command transcripts if useful.
Summary
On
@colbymchenry/codegraph@1.1.3, Codex MCP still becomes unstable on WSL2/mnt/deven with the recommended workaround from #974:The new distinguishing signal is that a single Codex parent process spawned two CodeGraph MCP server processes for the same physical repository with different path casing:
Both paths point to the same
.codegraph/codegraph.dbinode on DrvFs:After this, CLI
codegraph statusreported:Killing the repo-matching CodeGraph MCP processes made CLI
status/syncrecover, but the Codex MCP tool call then failed with:Environment
1.1.3v22.19.0/mnt/dDrvFs/mnt/d/02_SoftwareCodes/RCSS.Studio/Tekla/TeklaDrawingHelper_TeklaInternalObserved process state
pwdandpwd -Pfrom the active shell both showed the uppercase canonical-looking path:The Codex parent process also had the uppercase cwd:
But the same parent spawned two CodeGraph MCP server processes:
The Codex MCP tool call also carried the lower-case project path:
Daemon-related observation despite
CODEGRAPH_NO_DAEMON=1Even with
CODEGRAPH_NO_DAEMON=1in the MCP server environment,.codegraph/daemon.pidcontained a relocated daemon:{ "pid": 3607983, "version": "1.1.3", "socketPath": "/tmp/codegraph-befc5052950cc73f.sock", "startedAt": 1782718772179 }Process:
.codegraph/daemon.logincluded:This may be expected under some path, but it was surprising because the user-facing MCP process had
CODEGRAPH_NO_DAEMON=1.Symptoms
codegraph syncwas run.codegraph statusthen failed:statusrecovered andsynccompleted.Why this seems distinct from #974
#974 was on v1.1.0 and the recommended workaround was
CODEGRAPH_NO_DAEMON=1to skip the shared daemon on WSL2/mnt.In this case:
1.1.3.CODEGRAPH_NO_DAEMON=1.--no-watch..codegraph/daemon.pid.Transport closed.Expected behavior
On WSL2
/mnt/ DrvFs, CodeGraph should either:.codegraphownership, or.codegraphdirectory is opened through multiple path spellings.It should not allow two MCP processes from the same client parent to treat upper/lowercase spellings of the same DrvFs path as separate project roots while writing the same SQLite database.
Questions
CODEGRAPH_NO_DAEMON=1expected to fully prevent creation/use of a shared daemon in v1.1.3, or can a relocatedCODEGRAPH_DAEMON_INTERNAL=1process still appear?projectPathvalues that differ in casing from the server process cwd?I can provide additional command transcripts if useful.