Version
codebase-memory-mcp 0.9.1-rc.1
Platform
macOS (Apple Silicon)
Install channel
GitHub release archive / install.sh / install.ps1
Binary variant
standard
What happened, and what did you expect?
codebase-memory-mcp cli <tool> invoked with no flags blocks forever reading stdin whenever stdin is an open pipe that never delivers data. It produces no output and never exits.
This hits tools that legitimately need no arguments — list_projects is the obvious one. Passing any flag avoids it (index_status --project X and query_graph --project X --query "..." both complete normally against the same open-pipe stdin), so the trigger is specifically "no flags given → unconditionally read args from stdin".
That is a deadlock for automation. Any hook, CI step, git hook, or agent harness that runs cli list_projects while stdin is an inherited pipe hangs indefinitely rather than failing. I hit it by accident: a shell script doing
P=$(codebase-memory-mcp cli list_projects | grep -o '...' | head -1)
hung, and the process was still stuck 14 minutes later. A sample(1) of the stuck process shows the main thread parked in fread on fd 0:
2602 Thread_13001004 DispatchQueue_1: com.apple.main-thread (serial)
+ 2602 start (in dyld) + 6992
+ 2602 ??? (in codebase-memory-mcp) + 0x5474
+ 2602 ??? (in codebase-memory-mcp) + 0x5f9c
+ 2602 ??? (in codebase-memory-mcp) + 0x8768
+ 2602 fread (in libsystem_c.dylib) + 136
+ 2602 __fread (in libsystem_c.dylib) + 488
+ 2602 __srefill1 (in libsystem_c.dylib) + 36
+ 2602 _sread (in libsystem_c.dylib) + 32
+ 2602 __sread (in libsystem_c.dylib) + 24
+ 2602 __read_nocancel (in libsystem_kernel.dylib) + 8
Expected: only read stdin when it is actually ready/has data (select/poll with a zero timeout, or check isatty/S_ISFIFO plus a non-blocking peek), or only when the tool actually requires arguments that weren't supplied. A tool that needs no arguments should never block on stdin. Failing that, a short read timeout with a clear error beats an unbounded hang.
I assume this arrives with the RC's new "args via piped stdin" input path (echo '<json>' | codebase-memory-mcp cli <tool>, per the deprecation notice on raw-JSON args).
Reproduction
No repo needed — any indexed project, or none at all.
# stdin is an open pipe with a writer that never writes
mkfifo /tmp/cbm-fifo
sleep 120 > /tmp/cbm-fifo &
# hangs forever, zero bytes of output:
codebase-memory-mcp cli list_projects < /tmp/cbm-fifo
# control — returns immediately, 896 bytes:
codebase-memory-mcp cli list_projects < /dev/null
# control — flags present, same open-pipe stdin, completes fine:
codebase-memory-mcp cli index_status --project <some-project> < /tmp/cbm-fifo
Measured with a 12-second watchdog (perl -e 'alarm 12; exec @ARGV'):
| invocation |
stdin |
result |
cli list_projects |
FIFO, held open, no data |
hang, 0 bytes, killed by watchdog |
cli list_projects |
/dev/null |
exit 0, 896 bytes |
cli index_status --project cbm-rc-repros |
FIFO, held open, no data |
exit 0, 31,970 bytes |
cli query_graph --project cbm-rc-repros --query "MATCH (n) RETURN n.name LIMIT 1" |
FIFO, held open, no data |
exit 0, 50 bytes |
Confirmations
- I searched existing issues and this is not a duplicate.
- My reproduction uses shareable code (a dummy snippet or a public OSS repository), not proprietary code.
Posted by Claude Code on behalf of @artaommahe
Version
codebase-memory-mcp 0.9.1-rc.1
Platform
macOS (Apple Silicon)
Install channel
GitHub release archive / install.sh / install.ps1
Binary variant
standard
What happened, and what did you expect?
codebase-memory-mcp cli <tool>invoked with no flags blocks forever reading stdin whenever stdin is an open pipe that never delivers data. It produces no output and never exits.This hits tools that legitimately need no arguments —
list_projectsis the obvious one. Passing any flag avoids it (index_status --project Xandquery_graph --project X --query "..."both complete normally against the same open-pipe stdin), so the trigger is specifically "no flags given → unconditionally read args from stdin".That is a deadlock for automation. Any hook, CI step, git hook, or agent harness that runs
cli list_projectswhile stdin is an inherited pipe hangs indefinitely rather than failing. I hit it by accident: a shell script doingP=$(codebase-memory-mcp cli list_projects | grep -o '...' | head -1)hung, and the process was still stuck 14 minutes later. A
sample(1)of the stuck process shows the main thread parked infreadon fd 0:Expected: only read stdin when it is actually ready/has data (
select/pollwith a zero timeout, or checkisatty/S_ISFIFOplus a non-blocking peek), or only when the tool actually requires arguments that weren't supplied. A tool that needs no arguments should never block on stdin. Failing that, a short read timeout with a clear error beats an unbounded hang.I assume this arrives with the RC's new "args via piped stdin" input path (
echo '<json>' | codebase-memory-mcp cli <tool>, per the deprecation notice on raw-JSON args).Reproduction
No repo needed — any indexed project, or none at all.
Measured with a 12-second watchdog (
perl -e 'alarm 12; exec @ARGV'):cli list_projectscli list_projects/dev/nullcli index_status --project cbm-rc-reproscli query_graph --project cbm-rc-repros --query "MATCH (n) RETURN n.name LIMIT 1"Confirmations
Posted by Claude Code on behalf of @artaommahe