wiki: add claude-mem troubleshooting article for Claude Code 2.1 arg mismatch

claude-mem 12.1.3 passes --setting-sources with no value, which Claude Code
2.1.x rejects. Documents the silent summaryStored=null symptom, the real
error revealed under DEBUG logging, and the claude-shim workaround.
This commit is contained in:
2026-04-17 10:20:15 -04:00
parent 4f66955d33
commit 9c1a8c95d5
2 changed files with 180 additions and 1 deletions

View File

@@ -0,0 +1,178 @@
---
title: "claude-mem Silently Fails with Claude Code 2.1+ (Empty --setting-sources)"
domain: troubleshooting
category: claude-code
tags: [claude-code, claude-mem, cli, subprocess, version-mismatch, shim]
status: published
created: 2026-04-17
updated: 2026-04-17
---
# claude-mem Silently Fails with Claude Code 2.1+ (Empty `--setting-sources`)
## Symptom
After installing the `claude-mem` plugin (v12.1.3) in Claude Code (v2.1.112), every Claude Code session starts with:
```
No previous sessions found for this project yet.
```
…even for directories where you've worked repeatedly. Session records *do* appear in `~/.claude-mem/claude-mem.db` (table `sdk_sessions`), but:
- `session_summaries` count stays at **0**
- `observations` count stays at **0**
- Chroma vector DB stays empty
Tailing `~/.claude-mem/logs/claude-mem-YYYY-MM-DD.log` shows the Stop hook firing on every assistant turn, but always:
```
[HOOK ] → Stop: Requesting summary {hasLastAssistantMessage=true}
[HOOK ] Summary processing complete {waitedMs=503, summaryStored=null}
```
No errors, no stack traces — just a silent `null`. Raising `CLAUDE_MEM_LOG_LEVEL` to `DEBUG` reveals the true error:
```
[WARN ] [SDK_SPAWN] Claude process exited {code=1, signal=null, pid=…}
[ERROR] [SESSION] Generator failed {provider=claude, error=Claude Code process exited with code 1}
```
## Root cause
`claude-mem` 12.1.3 spawns the `claude` CLI as a subprocess to generate per-turn observations and session summaries. The argv it passes includes:
```
claude --output-format stream-json --verbose --input-format stream-json \
--model claude-sonnet-4-6 \
--disallowedTools Bash,Read,Write,… \
--setting-sources \ ← no value!
--permission-mode default
```
`claude-mem` intends to pass `--setting-sources ""` (empty string, meaning "no sources"). Claude Code **v2.1.x** now validates this flag and rejects empty values — it requires one of `user`, `project`, or `local`. With no value present, the CLI's argument parser consumes the next flag (`--permission-mode`) as the value and produces:
```
Error processing --setting-sources: Invalid setting source: --permission-mode.
Valid options are: user, project, local
```
The child process exits immediately with code 1 (within ~130 ms). `claude-mem` only logs `exited with code 1` and discards stderr by default, which is why the failure looks silent.
This is a **version-mismatch bug** between `claude-mem` 12.1.3 (latest as of 2026-04-17) and `claude-code` 2.1.x. Earlier Claude Code releases accepted empty values.
## Investigation path
1. Confirm worker processes are alive:
```bash
pgrep -fl "worker-service|mcp-server.cjs|chroma-mcp"
cat ~/.claude-mem/supervisor.json
```
2. Confirm sessions are being *recorded* but not *summarised*:
```bash
sqlite3 ~/.claude-mem/claude-mem.db \
"SELECT COUNT(*) FROM sdk_sessions; -- nonzero
SELECT COUNT(*) FROM session_summaries; -- 0 = pipeline broken
SELECT COUNT(*) FROM observations; -- 0 = pipeline broken"
```
3. Grep the log for `summaryStored=null` — if every Stop hook ends in `null`, summarisation is failing.
4. Raise log level to expose the real error:
```bash
# In ~/.claude-mem/settings.json
"CLAUDE_MEM_LOG_LEVEL": "DEBUG"
```
Kill and respawn workers (`pkill -f worker-service.cjs`). New logs should show `SDK_SPAWN Claude process exited {code=1}`.
5. Capture the exact argv by replacing `CLAUDE_CODE_PATH` with a debug shim that logs `$@` before exec'ing the real binary (see the fix below for the production shim — the debug version just tees argv to a log file).
## The fix
Apply in this order.
### 1. Fix the settings `claude-mem` ships with empty
Edit `~/.claude-mem/settings.json`:
```json
{
"CLAUDE_CODE_PATH": "/Users/you/.local/bin/claude-shim",
"CLAUDE_MEM_TIER_SUMMARY_MODEL": "claude-sonnet-4-6"
}
```
Both ship empty in a fresh install. `CLAUDE_CODE_PATH` points at the shim (below), not the real binary. `CLAUDE_MEM_TIER_SUMMARY_MODEL` is required when `CLAUDE_MEM_TIER_ROUTING_ENABLED=true`.
### 2. Install the shim
`/Users/you/.local/bin/claude-shim`:
```bash
#!/bin/bash
# Workaround shim for claude-mem 12.1.3 <-> Claude Code 2.1.x incompat.
# claude-mem passes `--setting-sources` with no value; Claude CLI 2.1+ rejects
# empty and consumes the next flag as the value. Fix: inject "user" when missing.
REAL=/Users/you/.local/bin/claude
new_args=()
i=0
args=("$@")
while [ $i -lt ${#args[@]} ]; do
cur="${args[$i]}"
new_args+=("$cur")
if [ "$cur" = "--setting-sources" ]; then
next="${args[$((i+1))]}"
case "$next" in
user|project|local) : ;; # already valid
*) new_args+=("user") ;; # inject missing value
esac
fi
i=$((i+1))
done
exec "$REAL" "${new_args[@]}"
```
Chmod it executable: `chmod +x ~/.local/bin/claude-shim`.
### 3. Restart workers
```bash
pkill -f "worker-service.cjs --daemon"
```
They respawn automatically on the next Claude Code hook fire. Verify:
```bash
# Within ~15 s:
sqlite3 ~/.claude-mem/claude-mem.db "SELECT COUNT(*) FROM observations;"
# Should be growing as you continue the session.
```
### 4. Sanity-check the shim is being used
```bash
ps -eww | grep -F 'setting-sources user'
```
Every live `claude` child should have `--setting-sources user` in its argv, not a bare `--setting-sources`.
## Why a shim instead of patching `claude-mem`
The offending code is inside the minified `worker-service.cjs` bundle shipped by `@anthropic-ai/claude-code` SDK, which `claude-mem` vendors. Patching the bundle is possible but fragile: any `claude-mem` update overwrites it. The shim is a one-file wrapper at a stable path, survives plugin updates, and becomes a no-op the moment upstream ships a fix.
## When to remove the shim
Check for a newer `claude-mem` release or an Anthropic SDK update that stops passing `--setting-sources` with an empty value. Test by:
1. Point `CLAUDE_CODE_PATH` back at the real `/Users/you/.local/bin/claude`.
2. Restart workers.
3. Confirm `observations` count keeps growing.
If it does, remove the shim. If not, restore the shim path and wait for a later release.
## Related
- Install notes: `20-Projects/Personal-Tasks.md` — "Install claude-mem plugin on MajorMac — 2026-04-15"
- Config file: `~/.claude-mem/settings.json`
- Logs: `~/.claude-mem/logs/claude-mem-YYYY-MM-DD.log`
- DB: `~/.claude-mem/claude-mem.db` (SQLite, FTS5 enabled)