Summary
memory_search intermittently fails with "memory_search timed out after 15s" + "Memory search is unavailable due to an embedding/provider error." (and sometimes a misleading "index metadata is missing"), even when the on-disk index is healthy. Root cause: the tool wraps the entire search — including the query-time embedding call to a cloud provider — in a single hardcoded 15s timeout that is not configurable.
Root cause (exact)
In dist/tools-CcIzM8pz.js (compiled; source equivalent in the memory-search tool):
const MEMORY_SEARCH_TOOL_TIMEOUT_MS = 15e3; // module-level const
// ...
timer = setTimeout(() => resolve("timeout"), params.timeoutMs);
// ...
error: `memory_search timed out after ${Math.round(params.timeoutMs / 1e3)}s`
// ...
timeoutMs: MEMORY_SEARCH_TOOL_TIMEOUT_MS,
- The 15s value is a module-level constant — not config- or env-overridable. The only memory timeout schema keys (
memory.qmd.update.*, memory.qmd.limits.timeoutMs) govern the qmd updater, not this race.
- A single slow embedding RTT (cold connection, provider blip) trips the whole tool, even though the local vector/FTS store would have answered instantly.
- A failure also records a tool cooldown (
recordMemorySearchToolCooldown), so subsequent calls can keep returning the unavailable result for a window after the provider has already recovered.
Repro
- Configure memory search with a cloud embedding provider (e.g. OpenAI
text-embedding-3-small).
- Issue
memory_search queries while the provider has elevated latency (or briefly throttle/delay the embedding endpoint).
- Observe
memory_search timed out after 15s and an "unavailable" result, while openclaw memory status shows the index healthy (embeddings: ready, FTS: ready, not dirty, meta table intact).
Impact
Low and self-healing, but operationally confusing: recall-side semantic search degrades for the provider blip + cooldown window, then recovers on its own. The "index metadata is missing" fallback string implies index corruption and sends operators down a reindex rabbit hole — when nothing is actually wrong with the index. (Observed on a live host 2026-06-06; index verified healthy throughout.)
Proposed fix (ranked)
- Make the timeout configurable via config (e.g.
memory.search.timeoutMs) and/or env. 15s is tight for a cold cloud-embedding RTT; remote-embedder operators want 30–45s.
- Separate the query-embed timeout from the local-store search so a slow provider doesn't mask an instant local FTS/vec result. A keyword-only graceful-degrade already exists on one path (
manager: "embeddings unavailable; using keyword-only results") — surface that on the tool path too instead of returning fully-unavailable.
- Fix the misleading fallback message — a provider/embed timeout should not report
"index metadata is missing". Distinguish provider-timeout from a genuine metadata/provider-mismatch so operators don't force needless reindexes.
Workaround (no code)
- Transient + self-healing; retry the query.
- The CLI path (
openclaw memory status) and the memory-episodic plugin's /memory-recall-* slash commands use different code paths and were unaffected.
- Do not force a reindex on this symptom alone — the index is fine; reindex only burns API calls and churns a healthy store.
Summary
memory_searchintermittently fails with"memory_search timed out after 15s"+"Memory search is unavailable due to an embedding/provider error."(and sometimes a misleading"index metadata is missing"), even when the on-disk index is healthy. Root cause: the tool wraps the entire search — including the query-time embedding call to a cloud provider — in a single hardcoded 15s timeout that is not configurable.Root cause (exact)
In
dist/tools-CcIzM8pz.js(compiled; source equivalent in the memory-search tool):memory.qmd.update.*,memory.qmd.limits.timeoutMs) govern the qmd updater, not this race.recordMemorySearchToolCooldown), so subsequent calls can keep returning the unavailable result for a window after the provider has already recovered.Repro
text-embedding-3-small).memory_searchqueries while the provider has elevated latency (or briefly throttle/delay the embedding endpoint).memory_search timed out after 15sand an "unavailable" result, whileopenclaw memory statusshows the index healthy (embeddings: ready,FTS: ready, not dirty,metatable intact).Impact
Low and self-healing, but operationally confusing: recall-side semantic search degrades for the provider blip + cooldown window, then recovers on its own. The
"index metadata is missing"fallback string implies index corruption and sends operators down a reindex rabbit hole — when nothing is actually wrong with the index. (Observed on a live host 2026-06-06; index verified healthy throughout.)Proposed fix (ranked)
memory.search.timeoutMs) and/or env. 15s is tight for a cold cloud-embedding RTT; remote-embedder operators want 30–45s.manager: "embeddings unavailable; using keyword-only results") — surface that on the tool path too instead of returning fully-unavailable."index metadata is missing". Distinguish provider-timeout from a genuine metadata/provider-mismatch so operators don't force needless reindexes.Workaround (no code)
openclaw memory status) and the memory-episodic plugin's/memory-recall-*slash commands use different code paths and were unaffected.