diff --git a/05-troubleshooting/claude-mem-setting-sources-empty-arg.md b/05-troubleshooting/claude-mem-setting-sources-empty-arg.md new file mode 100644 index 0000000..d24e550 --- /dev/null +++ b/05-troubleshooting/claude-mem-setting-sources-empty-arg.md @@ -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) diff --git a/05-troubleshooting/index.md b/05-troubleshooting/index.md index 1e3b9f5..99c323e 100644 --- a/05-troubleshooting/index.md +++ b/05-troubleshooting/index.md @@ -1,6 +1,6 @@ --- created: 2026-03-15T06:37 -updated: 2026-04-13T10:10 +updated: 2026-04-17T09:57 --- # 🔧 General Troubleshooting @@ -44,3 +44,4 @@ Practical fixes for common Linux, networking, and application problems. ## 🤖 AI / Local LLM - [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) +- [claude-mem Silently Fails with Claude Code 2.1+ (Empty `--setting-sources`)](claude-mem-setting-sources-empty-arg.md)