Skip to content

[Bug]: FTS-only memory search is completely broken — 0 chunks indexed when no embedding provider is configured #26792

Description

@qsysbio-cjw

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

  1. Fresh install OpenClaw 2026.2.23 (no OpenAI/Google/Voyage/Mistral API key configured)
  2. Create workspace memory files: MEMORY.md, memory/2026-02-25.md, etc.
  3. Run openclaw memory index --force
  4. 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

  1. Remove the three early returns — let file scanning and chunking proceed without provider.
  2. Add null-safe provider access:
    • this.provider.modelthis.provider?.model ?? "fts-only"
    • resolveEmbeddingMaxInputTokens(provider): add if (!provider) return DEFAULT_EMBEDDING_MAX_INPUT_TOKENS;
    • embedChunksInBatches(chunks): add if (!this.provider) return chunks.map(() => []);
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions