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:
178
05-troubleshooting/claude-mem-setting-sources-empty-arg.md
Normal file
178
05-troubleshooting/claude-mem-setting-sources-empty-arg.md
Normal 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)
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
created: 2026-03-15T06:37
|
created: 2026-03-15T06:37
|
||||||
updated: 2026-04-13T10:10
|
updated: 2026-04-17T09:57
|
||||||
---
|
---
|
||||||
# 🔧 General Troubleshooting
|
# 🔧 General Troubleshooting
|
||||||
|
|
||||||
@@ -44,3 +44,4 @@ Practical fixes for common Linux, networking, and application problems.
|
|||||||
## 🤖 AI / Local LLM
|
## 🤖 AI / Local LLM
|
||||||
- [Ollama Drops Off Tailscale When Mac Sleeps](ollama-macos-sleep-tailscale-disconnect.md)
|
- [Ollama Drops Off Tailscale When Mac Sleeps](ollama-macos-sleep-tailscale-disconnect.md)
|
||||||
- [Windows OpenSSH Server (sshd) Stops After Reboot](networking/windows-sshd-stops-after-reboot.md)
|
- [Windows OpenSSH Server (sshd) Stops After Reboot](networking/windows-sshd-stops-after-reboot.md)
|
||||||
|
- [claude-mem Silently Fails with Claude Code 2.1+ (Empty `--setting-sources`)](claude-mem-setting-sources-empty-arg.md)
|
||||||
|
|||||||
Reference in New Issue
Block a user