Before submitting
Related but not duplicates:
📝 Manual Bug Report
Bug Description
The UserPromptSubmit hook defined in plugin/hooks/hooks.json can exit with a non-zero status and zero bytes of stderr, producing the Claude Code error:
UserPromptSubmit hook error — Failed with non-blocking status code: No stderr output
The cause is in the shell command itself. The final step is:
[ "$_HEALTH" = "1" ] && node "$_R/scripts/bun-runner.js" "$_R/scripts/worker-service.cjs" hook claude-code session-init
There is no trailing || true. So whenever the worker's /health endpoint is not reachable within the 10×1s retry budget (worker restarting, cold start, transiently unhealthy, port mismatch, etc.), [ "$_HEALTH" = "1" ] evaluates to false, the whole shell command exits with status 1, and nothing is written to stderr. Claude Code surfaces it as the "No stderr output" error above.
Comparable branches in the same file (e.g. SessionStart session-init, which was hardened in #1794 via adding a || true / defensive echo ... || true) already guard against this. The UserPromptSubmit branch was not updated.
Checked all cached versions on the reporter's machine (12.1.5, 12.1.6, 12.2.0, 12.3.2, 12.3.7, 12.3.8, 12.3.9) and the command tail is byte-identical — the missing || true has been present since at least 12.1.5. The latest main on GitHub is also still affected.
Steps to Reproduce
- Install or run
claude-mem@12.3.9 in Claude Code.
- Stop the worker (
pkill -f worker-service.cjs) or otherwise make http://$HOST:$PORT/health unreachable.
- Submit any prompt.
- Claude Code shows:
UserPromptSubmit hook error — Failed with non-blocking status code: No stderr output.
It also reproduces intermittently in normal use (right at session start, after a crash, or when the worker is briefly busy enough to miss the 10-second retry budget).
Expected Behavior
When the worker is unreachable, the hook should exit 0 silently — the same contract the SessionStart session-init branch now uses. The end user should never see a non-zero status from this hook just because the worker had not yet come up.
Proposed Fix
Append || true (or equivalent) to the UserPromptSubmit command in plugin/hooks/hooks.json. For example:
- … [ "$_HEALTH" = "1" ] && node "$_R/scripts/bun-runner.js" "$_R/scripts/worker-service.cjs" hook claude-code session-init
+ … [ "$_HEALTH" = "1" ] && node "$_R/scripts/bun-runner.js" "$_R/scripts/worker-service.cjs" hook claude-code session-init || true
A stricter variant that keeps the "only run node when healthy" guard but never leaks a non-zero exit:
if [ "$_HEALTH" = "1" ]; then
node "$_R/scripts/bun-runner.js" "$_R/scripts/worker-service.cjs" hook claude-code session-init || true
fi
exit 0
Either way, the hook should match the graceful-degradation already applied to SessionStart in #1794.
Environment
- Claude-mem version: 12.3.9 (latest, released 2026-04-22)
- Claude Code version: 2.1.118
- OS: macOS Darwin arm64
- Platform: Claude Code (desktop/CLI)
- Node: v24.14.1
Logs
Worker health confirmed functional when captured:
$ curl -sf http://127.0.0.1:<port>/health
{"status":"ok","timestamp":<ts>,"activeSessions":2}
EXIT=0
When the worker is up, the hook's own session-init runs cleanly and returns {} with exit 0:
$ _R="~/.claude/plugins/cache/thedotmack/claude-mem/12.3.9"
$ node "$_R/scripts/bun-runner.js" "$_R/scripts/worker-service.cjs" hook claude-code session-init
{}
EXIT=0
The failure is entirely in the outer shell command when _HEALTH=0 — no log entry is produced because nothing inside the node handler is reached.
One related WARN observed in ~/.claude-mem/logs/claude-mem-YYYY-MM-DD.log (may or may not relate):
[WARN ] [HOOK ] session-init: No sessionId provided, skipping (Codex CLI or unknown platform)
This path already returns {continue:true, suppressOutput:true, exitCode: SUCCESS} in the handler, so it does not cause the shell-level non-zero exit.
Additional Context
The identical pattern exists in the SessionStart hook chain in older releases and was historically noisy; it was fixed by adding || true-style guards (see #1794, #1447). Applying the same fix to the UserPromptSubmit command closes the last remaining path that surfaces "No stderr output" to end users.
Before submitting
Related but not duplicates:
UserPromptSubmitbranch.📝 Manual Bug Report
Bug Description
The
UserPromptSubmithook defined inplugin/hooks/hooks.jsoncan exit with a non-zero status and zero bytes of stderr, producing the Claude Code error:The cause is in the shell command itself. The final step is:
There is no trailing
|| true. So whenever the worker's/healthendpoint is not reachable within the 10×1s retry budget (worker restarting, cold start, transiently unhealthy, port mismatch, etc.),[ "$_HEALTH" = "1" ]evaluates to false, the whole shell command exits with status 1, and nothing is written to stderr. Claude Code surfaces it as the "No stderr output" error above.Comparable branches in the same file (e.g.
SessionStartsession-init, which was hardened in #1794 via adding a|| true/ defensiveecho ... || true) already guard against this. TheUserPromptSubmitbranch was not updated.Checked all cached versions on the reporter's machine (
12.1.5,12.1.6,12.2.0,12.3.2,12.3.7,12.3.8,12.3.9) and the command tail is byte-identical — the missing|| truehas been present since at least12.1.5. The latestmainon GitHub is also still affected.Steps to Reproduce
claude-mem@12.3.9in Claude Code.pkill -f worker-service.cjs) or otherwise makehttp://$HOST:$PORT/healthunreachable.UserPromptSubmit hook error — Failed with non-blocking status code: No stderr output.It also reproduces intermittently in normal use (right at session start, after a crash, or when the worker is briefly busy enough to miss the 10-second retry budget).
Expected Behavior
When the worker is unreachable, the hook should exit 0 silently — the same contract the
SessionStartsession-init branch now uses. The end user should never see a non-zero status from this hook just because the worker had not yet come up.Proposed Fix
Append
|| true(or equivalent) to theUserPromptSubmitcommand inplugin/hooks/hooks.json. For example:A stricter variant that keeps the "only run node when healthy" guard but never leaks a non-zero exit:
Either way, the hook should match the graceful-degradation already applied to
SessionStartin #1794.Environment
Logs
Worker health confirmed functional when captured:
When the worker is up, the hook's own
session-initruns cleanly and returns{}with exit 0:The failure is entirely in the outer shell command when
_HEALTH=0— no log entry is produced because nothing inside the node handler is reached.One related WARN observed in
~/.claude-mem/logs/claude-mem-YYYY-MM-DD.log(may or may not relate):This path already returns
{continue:true, suppressOutput:true, exitCode: SUCCESS}in the handler, so it does not cause the shell-level non-zero exit.Additional Context
The identical pattern exists in the
SessionStarthook chain in older releases and was historically noisy; it was fixed by adding|| true-style guards (see #1794, #1447). Applying the same fix to theUserPromptSubmitcommand closes the last remaining path that surfaces "No stderr output" to end users.