Summary
memory_search returns empty results when no embedding provider is configured (FTS-only mode). Despite openclaw memory status reporting FTS: ready, the index contains 0 files / 0 chunks because the chunking pipeline is gated behind if (!this.provider) return; checks in three separate functions. FTS-only mode is advertised as a functional fallback but is effectively broken — no content is ever indexed.
Steps to reproduce
- Fresh install OpenClaw 2026.2.23 (no OpenAI/Google/Voyage/Mistral API key configured)
- Create workspace memory files:
MEMORY.md, memory/2026-02-25.md, etc.
- Run
openclaw memory index --force
- Run
openclaw memory status
Expected behavior
FTS-only mode should index memory files into the FTS table (chunking + full-text insertion), enabling keyword search without an embedding provider. memory_search should return relevant results based on keyword matching.
Actual behavior
Memory Search (main)
Provider: none (requested: auto)
Model: none
Sources: memory
Indexed: 0/15 files · 0 chunks ← should be 15/15
FTS: ready ← misleading: ready but empty
memory_search returns empty results for any query. Debug logs confirm:
[memory] Skipping memory file sync in FTS-only mode (no embedding provider)
OpenClaw version
2026.2.23
Operating system
Ubuntu Linux 6.17.0-14-generic (x64)
Install method
np install -g openclaw
Logs, screenshots, and evidence
Debug output with `OPENCLAW_LOG_LEVEL=debug openclaw memory index --force`:
**BEFORE patch:**
[memory] Skipping memory file sync in FTS-only mode (no embedding provider)
Memory index updated (main).
**AFTER patch:**
[memory] FTS-only mode: indexing memory files without vector embeddings
[memory] sync: indexing memory files
Memory index updated (main).
Result: `Indexed: 15/15 files · 34 chunks` ✅
Search works: `openclaw memory search "EvoMap"` → `1.000 memory/2026-02-25.md:1-17`
Impact and severity
High — Affects every user without an embedding API key (OpenAI/Google/Voyage/Mistral). This includes new users, air-gapped/proxy-restricted environments, and users who intentionally want lightweight FTS-only search. The misleading "FTS: ready" status makes diagnosis harder.
Additional information
Root Cause
Three functions in src/memory/manager.ts (compiled to multiple dist/manager-*.js bundles) bail out early when this.provider is null:
1. syncMemoryFiles():
if (!this.provider) {
log.debug("Skipping memory file sync in FTS-only mode (no embedding provider)");
return; // skips all file scanning
}
2. syncSessionFiles():
if (!this.provider) {
log.debug("Skipping session file sync in FTS-only mode (no embedding provider)");
return; // skips all session indexing
}
3. indexFile():
if (!this.provider) {
log.debug("Skipping embedding indexing in FTS-only mode");
return; // skips chunking + FTS insertion
}
The rest of indexFile() already handles null embeddings gracefully — FTS INSERT and chunk INSERT are independent of vector embeddings. The early returns are overly conservative.
Additionally, several places reference this.provider.model without null checks, which would crash if the early returns were simply removed.
Suggested Fix
- Remove the three early returns — let file scanning and chunking proceed without provider.
- Add null-safe provider access:
this.provider.model → this.provider?.model ?? "fts-only"
resolveEmbeddingMaxInputTokens(provider): add if (!provider) return DEFAULT_EMBEDDING_MAX_INPUT_TOKENS;
embedChunksInBatches(chunks): add if (!this.provider) return chunks.map(() => []);
- Vector table remains empty (no embeddings computed), FTS table gets populated.
Verified
Patched all 4 dist/manager-*.js bundles in v2026.2.23. Tested on two separate profiles:
- Main profile: 0→15 files, 0→34 chunks ✅
- Secondary profile: 0→1 files, 0→1 chunks ✅
Related
Summary
memory_searchreturns empty results when no embedding provider is configured (FTS-only mode). Despiteopenclaw memory statusreportingFTS: ready, the index contains 0 files / 0 chunks because the chunking pipeline is gated behindif (!this.provider) return;checks in three separate functions. FTS-only mode is advertised as a functional fallback but is effectively broken — no content is ever indexed.Steps to reproduce
MEMORY.md,memory/2026-02-25.md, etc.openclaw memory index --forceopenclaw memory statusExpected behavior
FTS-only mode should index memory files into the FTS table (chunking + full-text insertion), enabling keyword search without an embedding provider.
memory_searchshould return relevant results based on keyword matching.Actual behavior
memory_searchreturns empty results for any query. Debug logs confirm:OpenClaw version
2026.2.23
Operating system
Ubuntu Linux 6.17.0-14-generic (x64)
Install method
np install -g openclaw
Logs, screenshots, and evidence
Impact and severity
High — Affects every user without an embedding API key (OpenAI/Google/Voyage/Mistral). This includes new users, air-gapped/proxy-restricted environments, and users who intentionally want lightweight FTS-only search. The misleading "FTS: ready" status makes diagnosis harder.
Additional information
Root Cause
Three functions in
src/memory/manager.ts(compiled to multipledist/manager-*.jsbundles) bail out early whenthis.provideris null:1.
syncMemoryFiles():2.
syncSessionFiles():3.
indexFile():The rest of
indexFile()already handles null embeddings gracefully — FTS INSERT and chunk INSERT are independent of vector embeddings. The early returns are overly conservative.Additionally, several places reference
this.provider.modelwithout null checks, which would crash if the early returns were simply removed.Suggested Fix
this.provider.model→this.provider?.model ?? "fts-only"resolveEmbeddingMaxInputTokens(provider): addif (!provider) return DEFAULT_EMBEDDING_MAX_INPUT_TOKENS;embedChunksInBatches(chunks): addif (!this.provider) return chunks.map(() => []);Verified
Patched all 4
dist/manager-*.jsbundles in v2026.2.23. Tested on two separate profiles:Related