You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Daemon fails with ENOTSUP on ExFAT / external volumes (no tmpdir fallback for unsupported socket) #997
When a project lives on an ExFAT-formatted external volume (e.g. /Volumes/zwl/xjp/my-project), the daemon fails to start because ExFAT does not support Unix domain sockets. The listen() call throws ENOTSUP.
The existing code in daemon-paths.ts already has a tmpdir fallback for long socket paths (> 100 chars), but there is no fallback for filesystems that don't support sockets at all.
Error
✗ Failed to start server: listen ENOTSUP: operation not supported on socket /Volumes/zwl/xjp/my-project/.codegraph/daemon.sock
(daemon.log keeps accumulating this error on every daemon spawn attempt.)
Environment
CodeGraph version: 1.1.1
OS: macOS 26.0.1 (Darwin 25.0.0, Apple Silicon)
Filesystem: ExFAT (external USB drive)
Socket path length: 49 chars (well under the 100-char limit, so the tmpdir fallback is not triggered)
Root Cause
In daemon-paths.js, getDaemonSocketPath() only falls back to os.tmpdir() when inProject.length > POSIX_SOCKET_PATH_LIMIT:
functiongetDaemonSocketPath(projectRoot){constinProject=path.join(getCodeGraphDir(projectRoot),'daemon.sock');if(inProject.length<=POSIX_SOCKET_PATH_LIMIT)returninProject;// ← ExFAT hits this branch, then listen() failsreturnpath.join(os.tmpdir(),`codegraph-${projectHash(projectRoot)}.sock`);}
The daemon's start() method (daemon.js) catches the ENOTSUP from linkSync (pid lockfile) and falls back to renameSync, but there is no equivalent fallback for the socket listen() call — it just cleans up and re-throws, killing the daemon.
Suggested Fix
When server.listen() fails with ENOTSUP (or ENOTSOCK / EACCES), retry with a tmpdir-based socket path — the same path getDaemonSocketPath already computes for the long-path case:
// In Daemon.start(), after the first listen fails:if(err.code==='ENOTSUP'||err.code==='ENOTSOCK'){this.socketPath=path.join(os.tmpdir(),`codegraph-${projectHash(projectRoot)}.sock`);// retry listen on tmpdir path}
Or proactively detect non-socket-capable filesystems in getDaemonSocketPath() itself.
Impact
Daemon (background auto-sync): broken — no automatic incremental indexing on file changes.
MCP tool (codegraph_explore): works fine (in-process, no daemon needed).
prompt-hook: works fine (in-process).
Manual codegraph index/sync: works fine.
So the functional impact is limited to losing automatic background indexing — users must run codegraph sync . manually after significant changes. But the repeated error in daemon.log is noisy.
Workaround
Run codegraph index . or codegraph sync . manually to refresh the index.
Fixed in #1022 — merged to main, ships in the next release.
Thanks for the unusually precise report; it made this fast to reproduce. Reproducing it on a real ExFAT volume actually turned up a second failure your logs hadn't reached yet: before the socket listen() runs, the daemon's lockfile step hard-links a temp file onto .codegraph/daemon.pid, and ExFAT/FAT don't support hard links either — so that throws first. Both are fixed now:
Lockfile: falls back to an exclusive O_EXCL create when the filesystem has no hard links.
Socket: the daemon relocates its socket to the system temp directory when the project's filesystem can't host one, and the proxy follows it there automatically — no config needed.
Rather than special-casing ExFAT's specific error code, the fix triggers on the capability failure generically. That turned out to matter: the three OSes report three different errnos for the same gap — macOS ENOTSUP, Linux EPERM, Windows EISDIR — so it's validated end-to-end on real ExFAT/FAT volumes across macOS, Linux, and Windows.
Once this releases you won't need the manual codegraph sync workaround — background indexing will just work on the external drive. Thanks again! 🙏
Activity
fix(mcp): start the daemon on ExFAT/FAT/network filesystems (#997) (#…
colbymchenry commentedon Jun 27, 2026
Fixed in #1022 — merged to
main, ships in the next release.Thanks for the unusually precise report; it made this fast to reproduce. Reproducing it on a real ExFAT volume actually turned up a second failure your logs hadn't reached yet: before the socket
listen()runs, the daemon's lockfile step hard-links a temp file onto.codegraph/daemon.pid, and ExFAT/FAT don't support hard links either — so that throws first. Both are fixed now:O_EXCLcreate when the filesystem has no hard links.Rather than special-casing ExFAT's specific error code, the fix triggers on the capability failure generically. That turned out to matter: the three OSes report three different errnos for the same gap — macOS
ENOTSUP, LinuxEPERM, WindowsEISDIR— so it's validated end-to-end on real ExFAT/FAT volumes across macOS, Linux, and Windows.Once this releases you won't need the manual
codegraph syncworkaround — background indexing will just work on the external drive. Thanks again! 🙏