openclaw - ✅(Solved) Fix memory_search: qmd validation rejects hyphenated tokens, causes total fallback to builtin index [1 pull requests, 2 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#81328Fetched 2026-05-14 03:33:16
View on GitHub
Comments
2
Participants
3
Timeline
3
Reactions
2
Timeline (top)
commented ×2cross-referenced ×1

memory_search falls back to the builtin index whenever the query contains hyphenated tokens (e.g. sqlite-vec, 2026-05-04, multi-agent). The root cause is in qmd (tobi/qmd#414, tobi/qmd#618), but OpenClaw amplifies the impact: a single sub-search validation failure aborts the entire qmd.query response, taking down lex even though lex doesn't care about hyphens.

Error Message

  1. Any sub-search validation error → the whole qmd.query returns isError: true.

Root Cause

memory_search falls back to the builtin index whenever the query contains hyphenated tokens (e.g. sqlite-vec, 2026-05-04, multi-agent). The root cause is in qmd (tobi/qmd#414, tobi/qmd#618), but OpenClaw amplifies the impact: a single sub-search validation failure aborts the entire qmd.query response, taking down lex even though lex doesn't care about hyphens.

Fix Action

Fix / Workaround

Code refs (in the bundled CLI):

  • tools-B3jFTrn6.js:324
  • qmd-manager-D-Df6uBI.js:1184-1212buildV2Searches(), no sanitization before dispatch.

This decouples OpenClaw from the upstream qmd fix timeline. Once qmd ships #618, the workaround becomes a no-op.

PR fix notes

PR #81423: fix(memory): preserve qmd lexical search for hyphenated queries

Description (problem / solution / changelog)

Summary

  • Preserve the raw user query for QMD lexical (lex) searches so dashed identifiers, dates, and version strings can still match exactly.
  • Normalize only QMD semantic sub-searches (vec / hyde) by replacing word-internal hyphens with spaces before sending the v2 qmd.query searches array.
  • Add focused coverage for hybrid and vector-only QMD MCP payloads.

Fixes #81328.

Tests

  • node scripts/test-projects.mjs extensions/memory-core/src/memory/qmd-manager.test.ts --reporter=verbose -t "hyphenated tokens|vector-only QMD"
  • node scripts/test-projects.mjs extensions/memory-core/src/memory/search-manager.test.ts --reporter=verbose -t "falls back to builtin search when qmd fails with sqlite busy|keeps original qmd error when fallback manager initialization fails"
  • pnpm check:changed
  • git diff --check

Full qmd-manager.test.ts run on Windows reached 104/105 passing; the remaining failure was the existing symlink-permission case (EPERM creating a symlink), unrelated to this change.

Real behavior proof

Behavior addressed: memory_search should not lose QMD lexical recall just because a query contains hyphenated tokens such as sqlite-vec, 2026-05-04, or multi-agent.

Real environment tested: Local Windows source checkout at C:\src\openclaw-pr-81328 running the OpenClaw test harness for the QMD manager. The local machine does not have the qmd binary installed, so this draft has source-level/runtime-boundary proof rather than a live QMD daemon proof.

Exact steps or command run after this patch: Ran the focused QMD manager regression tests for the v2 qmd.query payload construction and the focused fallback-manager checks listed above.

Evidence after fix: The focused QMD manager test captures the exact mcporter call qmd.query arguments and verifies this payload shape for a dashed query:

{
  "searches": [
    { "type": "lex", "query": "sqlite-vec backend health 2026-05-04 multi-agent" },
    { "type": "vec", "query": "sqlite vec backend health 2026 05 04 multi agent" },
    { "type": "hyde", "query": "sqlite vec backend health 2026 05 04 multi agent" }
  ]
}

The vector-only regression verifies vsearch also sends the semantic-safe query:

{
  "searches": [
    { "type": "vec", "query": "sqlite vec backend health" }
  ]
}

Observed result after fix: The lexical branch keeps the raw query, so QMD can still match dashed identifiers and dates. The semantic branches no longer receive word-internal hyphens that QMD v2.0.1 treats as NOT-operator syntax, avoiding the validation failure that forced OpenClaw to fall back to the builtin index.

What was not tested: I did not run a live QMD 2.0.1 daemon or a full memory_search command against an installed QMD index in this environment. The PR is draft until we either get live QMD proof or a maintainer accepts the focused boundary test proof.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • extensions/memory-core/src/memory/qmd-manager.test.ts (modified, +74/-0)
  • extensions/memory-core/src/memory/qmd-manager.ts (modified, +8/-3)

Code Example

memory_search(query="sqlite-vec backend health")
# → returns provider:"none" with fallback.reason mentioning validation

---

const semanticQuery = rawQuery.replace(/(\w)-(\w)/g, '$1 $2');
// vec & hyde use semanticQuery; lex uses rawQuery
RAW_BUFFERClick to expand / collapse

Summary

memory_search falls back to the builtin index whenever the query contains hyphenated tokens (e.g. sqlite-vec, 2026-05-04, multi-agent). The root cause is in qmd (tobi/qmd#414, tobi/qmd#618), but OpenClaw amplifies the impact: a single sub-search validation failure aborts the entire qmd.query response, taking down lex even though lex doesn't care about hyphens.

Reproduce

memory_search(query="sqlite-vec backend health")
# → returns provider:"none" with fallback.reason mentioning validation

Root cause chain

  1. qmd's validateSemanticQuery regex /-\w/ flags any -X as a NOT operator, including word-internal hyphens.
  2. OpenClaw's memory_search runs lex + vec + hyde in parallel via buildV2Searches().
  3. Any sub-search validation error → the whole qmd.query returns isError: true.
  4. OpenClaw treats that as fatal → falls back to the builtin lex index.
  5. Result: lex (which would have worked on the raw query) is also lost.

Code refs (in the bundled CLI):

  • tools-B3jFTrn6.js:324
  • qmd-manager-D-Df6uBI.js:1184-1212buildV2Searches(), no sanitization before dispatch.

Impact

  • ~26× slower memory recall (builtin vs qmd vec, measured locally)
  • Loss of semantic ranking
  • Affects any query mentioning version strings, dates, or dashed identifiers — extremely common in dev/ops contexts

Suggested fix

Sanitize the query for vec/hyde paths only; keep the raw query for lex:

const semanticQuery = rawQuery.replace(/(\w)-(\w)/g, '$1 $2');
// vec & hyde use semanticQuery; lex uses rawQuery

This decouples OpenClaw from the upstream qmd fix timeline. Once qmd ships #618, the workaround becomes a no-op.

Alternative

Make qmd validation errors non-fatal at the OpenClaw layer: log and skip the failing sub-search, return whatever the others produce. This is more general and handles future qmd validation regressions too.

Environment

  • OpenClaw 2026.5.7 (eeef486)
  • qmd 2.0.1
  • macOS (Darwin 25.3.0 arm64), Node v24.14.1

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix memory_search: qmd validation rejects hyphenated tokens, causes total fallback to builtin index [1 pull requests, 2 comments, 3 participants]