Repository navigation
Stop-hook → /summarize → agent-sdk infinite recursion when no provider key is set (extends #149) #181
Description
Summary
On v0.9.1, a user with no provider API key set (and AGENTMEMORY_AUTO_COMPRESS=false — which they believed protected them) hits an infinite recursion loop. The Stop hook POSTs to /agentmemory/summarize, which unconditionally spawns a @anthropic-ai/claude-agent-sdk child session via the agent-sdk provider. That child session inherits the same plugin hooks → its own Stop fires → another child spawns → recursion.
This extends #149: that issue added a stderr warning but no actual guard. The user in this report had AGENTMEMORY_AUTO_COMPRESS=false in ~/.agentmemory/.env (per the warning's intended effect) and still hit the loop because /summarize does not consult AUTO_COMPRESS.
Observed impact
- ~579 ghost
entrypoint: sdk-tschild sessions accumulated in.claude/projects/C--Users-<home>/over a few minutes - Each child burns Claude Pro subscription tokens (SDK inherits CC OAuth when no API key is present)
- Dashboard unusable — sessions grow faster than it can render
- User had to kill the MCP server and manually clean up
Root cause (v0.9.1)
src/hooks/stop.ts:28—Stophook unconditionally POSTs/agentmemory/summarizewith onlysession_id. No parentage / SDK-child / cwd check.src/functions/summarize.ts:75-77— handler always callsprovider.summarize(...).AGENTMEMORY_AUTO_COMPRESSis never consulted on this path (it only gates/compress).src/config.ts:44-98—detectProvider()with all provider keys empty/unset falls through toreturn { provider: 'agent-sdk', ... }at L93-L97.AUTO_COMPRESSis only used to emit a stderr warning (L84-L92), not as a gate.src/providers/agent-sdk.ts:14-33— calls@anthropic-ai/claude-agent-sdkquery()which creates a full CC-style child session that reads~/.claude/settings.json, registers the same plugin hooks, and firesStopon exit.- Empty
ANTHROPIC_API_KEY=in.envis truthiness-checked atsrc/config.ts:56—\"\"is falsy, so it behaves identically to unset.
Minimum repro
- Fresh install of the agentmemory CC plugin at v0.9.1
~/.agentmemory/.envcontainsANTHROPIC_API_KEY=(or no key line at all) andAGENTMEMORY_AUTO_COMPRESS=falsenpx @agentmemory/agentmemoryrunning (cwd anywhere — home dir amplifies visibility but not required)- Open CC, do anything, exit —
Stopfires → loop kicks off - Watch
.claude/projects/<server-cwd-encoded>/fill withentrypoint: sdk-tssessions
Suggested fixes (any one breaks the loop)
- Gate the agent-sdk fallback on
AGENTMEMORY_AUTO_COMPRESS=trueindetectProvider(). IfAUTO_COMPRESSis false/unset AND no provider key is set, return a null/no-op provider and have/summarizeshort-circuit. The current warning suggests this was the intent. - Skip the Stop hook when the session is an SDK child. Either pass
entrypointinto the hook stdin payload (CC exposes it in the jsonl metadata already) and check forsdk-tsinsrc/hooks/stop.ts, or set an env marker (AGENTMEMORY_SDK_CHILD=1) whensrc/providers/agent-sdk.tsspawnsquery()and honor it in the hook script. - Treat empty-string provider keys as unset with a loud warning, and refuse to start in agent-sdk mode without an explicit opt-in flag like
AGENTMEMORY_ALLOW_AGENT_SDK=true.
Local workaround (documented here so others find it)
Set a fake ANTHROPIC_API_KEY=sk-ant-fake in ~/.agentmemory/.env. detectProvider() selects the anthropic provider, the real API returns 401, summarize.ts:148 catches and returns {success:false}, and the Stop hook's fetch().catch(() => {}) swallows it. No child session spawned. Confirmed safe as long as FALLBACK_PROVIDERS=agent-sdk is NOT set.
Why this is nastier than #149 suggests
The warning text in #149 implies setting AUTO_COMPRESS=false prevents the problem. It doesn't — it only prevents it on /compress, while /summarize is the actual hot path (fires on every Stop). A user following the warning's implied guidance still gets hit.
Activity
MaiHHConnect commentedon Apr 21, 2026
💬 我也在做记忆系统相关的工作:CausaMem,可以来看看,说不定有能借鉴的地方 🙂
rohitg00 commentedon Apr 22, 2026
@MaiHHConnect stop spamming, please on every issues.
rohitg00 commentedon Apr 26, 2026
Closing this — fixes from your repro all landed in v0.9.x:
src/config.ts). Loud stderr warning explains the trade-off and how to opt in.AGENTMEMORY_SDK_CHILD=1env marker +entrypoint=sdk-tscheck (src/hooks/stop.ts).query()and restores on finally (src/providers/agent-sdk.ts).FALLBACK_PROVIDERS=agent-sdkis filtered out unlessAGENTMEMORY_ALLOW_AGENT_SDK=true(src/config.ts).Regression tests in
test/stop-hook-recursion-guard.test.tscover the env-marker, payload-shape, and provider-gate cases.Thanks @josephwylie for the painstaking writeup — the file:line pointers and the impact-vs-#149 comparison were exactly what we needed to ship the fix.
fix(agent-sdk): scope recursion guard to AsyncLocalStorage, memoize S…
fix(agent-sdk): scope recursion guard to AsyncLocalStorage, memoize S…