Bug type
Behavior bug (incorrect output/state without crash)
Beta release blocker
No
Summary
After an active-memory embedded recall run times out, chat-session memory_search can return "memory search manager is closed" even though openclaw memory search --agent main succeeds against the same QMD backend.
Steps to reproduce
- Run OpenClaw with
memory-core using the QMD backend for agent main.
- Enable the
active-memory plugin for main with a short enough timeout to reproduce timeout behavior, for example timeoutMs: 5000 and queryMode: "message".
- Use an active-memory model/path that times out during the embedded recall run.
- Send a normal user message that triggers active-memory before prompt build.
- Observe active-memory timeout logs similar to
active-memory: agent=main ... done status=timeout elapsedMs=10007 summaryChars=0.
- Immediately call the chat-session
memory_search tool in the same gateway/session.
- Observe
memory_search returning unavailable with error: "memory search manager is closed".
- In parallel, run
openclaw memory search "<same topic>" --agent main from CLI and observe that CLI search succeeds.
Expected behavior
An active-memory timeout should cancel or skip only that active-memory recall attempt. It should not close the long-lived/shared QMD manager used by normal chat-session memory_search calls.
Chat memory_search should remain available when the QMD backend is healthy and CLI search for the same agent works.
Actual behavior
After active-memory times out, chat-session memory_search returns a disabled/unavailable result like:
{
"results": [],
"disabled": true,
"unavailable": true,
"error": "memory search manager is closed",
"action": "Check embedding provider configuration and retry memory_search."
}
The first closed-manager result can also put the memory tool into its 60s cooldown, so subsequent chat memory_search calls keep returning unavailable without immediately recreating a fresh manager.
OpenClaw version
Observed on 2026.6.9 (c645ec4). Current main source inspected at 1069c60e1e still contains the same active-memory timeout cleanup shape.
Operating system
macOS 26.5.1 (25F80)
Install method
NOT_ENOUGH_INFO
Model
active-memory model observed: openrouter/openai/gpt-oss-20b
Provider / routing chain
OpenClaw gateway -> active-memory embedded agent -> memory_search / memory_get; memory backend is QMD via /opt/homebrew/bin/qmd.
Additional provider/model setup details
Relevant observed setup:
- Node:
v26.3.0
- qmd:
2.5.3 (686144996e)
- Memory backend: QMD
- QMD search mode: lexical
searchMode: "search"
- active-memory agents:
["main"]
- active-memory timeoutMs:
5000
- active-memory default tools:
memory_search, memory_get
Logs, screenshots, and evidence
Observed gateway timeline, local time UTC+8:
19:31:24 active-memory: agent=main start timeoutMs=5000
19:31:34 qmd watcher starting for agent "main" paths=2
19:31:34 qmd manager initialized for agent "main" mode=full collections=2
19:31:34 qmd watcher ready for agent "main"
19:31:34 qmd sync completed for agent "main" reason=boot
19:31:35 active-memory: agent=main done status=timeout elapsedMs=10007
19:31:37 embedded abort settle timed out: runId=active-memory-...
19:31:37 embedded run failover decision: aborted=true decision=surface_error
After this, three chat memory_search tool calls returned "memory search manager is closed". The pattern repeated after later active-memory timeouts. CLI search continued to succeed for the same agent/backend.
Source evidence from current main (1069c60e1e):
extensions/active-memory/index.ts
- DEFAULT_ACTIVE_MEMORY_TOOLS_ALLOW is ["memory_search", "memory_get"].
- runRecallSubagent calls api.runtime.agent.runEmbeddedAgent(... toolsAllow: [...params.config.toolsAllow], abortSignal: params.abortSignal ...).
- maybeResolveActiveRecall schedules timeout cleanup on active-memory timeout/parent abort.
- scheduleMemorySearchCleanupAfterTimeout calls closeActiveMemorySearchManager({ cfg, agentId }).
extensions/memory-core/src/memory/search-manager.ts
- QMD full managers are cached by buildQmdManagerScopeKey(agentId), currently just the agent id.
- Non-status, non-cli callers receive the cached full manager.
- closeMemorySearchManager deletes QMD_MANAGER_CACHE[agentId] and calls cached.manager.close().
- FallbackMemoryManager.close() sets closed=true.
- FallbackMemoryManager.ensureOpen() throws "memory search manager is closed".
extensions/memory-core/src/tools.ts
- memory_search only tracks/closes managers for oneShotCliRun / purpose="cli".
- normal chat memory_search does not close the shared manager itself.
- memory_search treats "memory search manager is closed" as a closed-store error and may retry once, but the first unavailable result can still enter the tool cooldown path.
src/gateway/server-startup-memory.ts
- startup uses purpose="default" when a long-lived QMD manager is needed for timers/intervals, and purpose="cli" only for one-shot boot sync.
This points to active-memory timeout cleanup closing an agent-scoped shared QMD manager, rather than only aborting the request-scoped embedded recall.
Impact and severity
Affected: users with active-memory enabled and QMD-backed memory_search in chat sessions.
Severity: High for memory-dependent workflows. When it triggers, chat memory recall becomes unavailable even though QMD and CLI search are healthy.
Frequency: Reproduces after active-memory timeout in the observed setup; repeated timeouts can repeatedly re-close the manager.
Consequence: the agent appears to have broken or disabled memory, and the 60s memory_search cooldown can make recovery look sticky until cooldown expires or the gateway is restarted.
Additional information
Related but not duplicate issues found before filing:
This issue is narrower: active-memory timeout cleanup closes the shared QMD full manager used by chat memory_search, causing the specific "memory search manager is closed" failure.
Possible fix directions:
- Remove or narrow active-memory's timeout cleanup so it does not call
closeActiveMemorySearchManager for the agent-scoped shared full manager.
- Treat active-memory timeout as request-scoped cancellation only; rely on the embedded run abort signal and the memory_search tool's own abort signal to cancel in-flight QMD subprocess work.
- If active-memory needs disposable memory-search resources, run its internal recall against an isolated one-shot/CLI-style manager that is not stored in the shared full-manager cache.
- Add a regression test where an active-memory timeout overlaps with a normal chat
memory_search; the normal tool call should not surface "memory search manager is closed" and should either complete or recreate a fresh manager without entering cooldown.
- Consider not recording closed-manager errors into the 60s memory_search cooldown, because this is usually a lifecycle/race recovery case rather than an embedding-provider outage.
Bug type
Behavior bug (incorrect output/state without crash)
Beta release blocker
No
Summary
After an
active-memoryembedded recall run times out, chat-sessionmemory_searchcan return"memory search manager is closed"even thoughopenclaw memory search --agent mainsucceeds against the same QMD backend.Steps to reproduce
memory-coreusing the QMD backend for agentmain.active-memoryplugin formainwith a short enough timeout to reproduce timeout behavior, for exampletimeoutMs: 5000andqueryMode: "message".active-memory: agent=main ... done status=timeout elapsedMs=10007 summaryChars=0.memory_searchtool in the same gateway/session.memory_searchreturning unavailable witherror: "memory search manager is closed".openclaw memory search "<same topic>" --agent mainfrom CLI and observe that CLI search succeeds.Expected behavior
An active-memory timeout should cancel or skip only that active-memory recall attempt. It should not close the long-lived/shared QMD manager used by normal chat-session
memory_searchcalls.Chat
memory_searchshould remain available when the QMD backend is healthy and CLI search for the same agent works.Actual behavior
After active-memory times out, chat-session
memory_searchreturns a disabled/unavailable result like:{ "results": [], "disabled": true, "unavailable": true, "error": "memory search manager is closed", "action": "Check embedding provider configuration and retry memory_search." }The first closed-manager result can also put the memory tool into its 60s cooldown, so subsequent chat
memory_searchcalls keep returning unavailable without immediately recreating a fresh manager.OpenClaw version
Observed on
2026.6.9 (c645ec4). Currentmainsource inspected at1069c60e1estill contains the same active-memory timeout cleanup shape.Operating system
macOS 26.5.1 (25F80)
Install method
NOT_ENOUGH_INFO
Model
active-memory model observed:
openrouter/openai/gpt-oss-20bProvider / routing chain
OpenClaw gateway -> active-memory embedded agent ->
memory_search/memory_get; memory backend is QMD via/opt/homebrew/bin/qmd.Additional provider/model setup details
Relevant observed setup:
v26.3.02.5.3 (686144996e)searchMode: "search"["main"]5000memory_search,memory_getLogs, screenshots, and evidence
Observed gateway timeline, local time UTC+8:
After this, three chat
memory_searchtool calls returned"memory search manager is closed". The pattern repeated after later active-memory timeouts. CLI search continued to succeed for the same agent/backend.Source evidence from current
main(1069c60e1e):This points to active-memory timeout cleanup closing an agent-scoped shared QMD manager, rather than only aborting the request-scoped embedded recall.
Impact and severity
Affected: users with
active-memoryenabled and QMD-backedmemory_searchin chat sessions.Severity: High for memory-dependent workflows. When it triggers, chat memory recall becomes unavailable even though QMD and CLI search are healthy.
Frequency: Reproduces after active-memory timeout in the observed setup; repeated timeouts can repeatedly re-close the manager.
Consequence: the agent appears to have broken or disabled memory, and the 60s memory_search cooldown can make recovery look sticky until cooldown expires or the gateway is restarted.
Additional information
Related but not duplicate issues found before filing:
This issue is narrower: active-memory timeout cleanup closes the shared QMD full manager used by chat
memory_search, causing the specific"memory search manager is closed"failure.Possible fix directions:
closeActiveMemorySearchManagerfor the agent-scoped shared full manager.memory_search; the normal tool call should not surface"memory search manager is closed"and should either complete or recreate a fresh manager without entering cooldown.