#21868: fix: qmd search/vsearch silently return empty with multiple -c collection flags (#21865)
size: XS
## Problem
Fixes #21865
`memory_search` always returns `{ results: [], provider: "qmd" }` for agents with 2+ collections configured. No error is surfaced; agents silently behave as if memory is blank.
### Root cause
When `searchMode` is `"search"` or `"vsearch"` (the default), `search()` passes all managed collection names as simultaneous `-c` flags:
```
qmd search "query" --json -n 5 -c col1 -c col2 -c col3 -c col4 -c col5 -c col6
```
QMD 1.0.x returns empty results (exit 0, no error) when multiple `-c` flags are passed to `search`/`vsearch`. Because there's no exception thrown, the existing `isUnsupportedQmdOptionError` fallback never fires.
The existing `runQueryAcrossCollections()` workaround correctly handles this by iterating each collection separately, but it was only used for `searchMode: "query"`.
### Reproduction
```bash
# Silently returns empty:
qmd search "test" --json -n 5 -c col1 -c col2 -c col3 -c col4 -c col5 -c col6
# → No results found
# Works (single -c per call):
qmd search "test" --json -n 5 -c col1
# → results ✅
```
## Fix
Extend the multi-collection workaround to **all** search modes, not just `"query"`. When multiple collections are configured, `runQueryAcrossCollections()` is always used — one call per collection, results merged by best score per doc.
`runQueryAcrossCollections()` gains an optional `searchMode` parameter (default `"query"`) so the configured mode is preserved.
A single-collection search still uses the direct `-c` path since that works correctly.
## Changes
- `src/memory/qmd-manager.ts`
- `search()`: condition `qmdSearchCommand === "query" && collectionNames.length > 1` → `collectionNames.length > 1`
- `runQueryAcrossCollections()`: add optional `searchMode` param (default `"query"`), use it in `buildSearchArgs`
- Catch block simplified: multi-collection branch removed (now unreachable); single-collection fallback retained
## Testing
Verified locally on OpenClaw 2026.2.17 / QMD 1.0.6 / qmd-cli 1.1.0:
- With `searchMode: "search"` (default) + 6 collections: `memory_search` now returns results ✅
- With `searchMode: "query"` + 6 collections: unchanged, still works ✅
- With `searchMode: "vsearch"` + 6 collections: now works (same fix applies) ✅
- Single collection: unchanged, direct `-c` path still used ✅
Workaround (while awaiting merge): set `memory.qmd.searchMode: "query"` in config.
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
extends multi-collection workaround from `query` mode to all search modes (`search`, `vsearch`) to fix silent empty results when agents have 2+ collections configured
**Key improvement:**
- main search path now correctly routes all multi-collection searches through `runQueryAcrossCollections` regardless of search mode, preventing the silent failure from passing multiple `-c` flags to qmd 1.0.x
**Issue found:**
- error fallback path (lines 429-434) doesn't properly handle multiple collections - when `runQueryAcrossCollections` throws an error, the fallback builds query args with multiple `-c` flags, recreating the exact bug this PR fixes. the old multi-collection branch in the catch block should be restored.
<h3>Confidence Score: 2/5</h3>
- contains logic error in error handling that could recreate the bug being fixed
- while the main fix correctly routes multi-collection searches through the workaround, the error fallback path has a logic bug that can still trigger the silent failure with multiple `-c` flags when the first collection attempt fails. this significantly undermines the fix's effectiveness in edge cases.
- `src/memory/qmd-manager.ts` lines 429-434 need correction to properly handle multi-collection fallback
<sub>Last reviewed commit: 7c89cfc</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#16968: fix(qmd): per-collection search to prevent large collections drowni...
by ProgramCaiCai · 2026-02-15
91.4%
#22937: fix: remove legacy unsuffixed QMD collections on upgrade
by sud0n1m-ziggy · 2026-02-21
82.8%
#20966: fix(memory/qmd): migrate orphaned unscoped collections on upgrade
by marcodelpin · 2026-02-19
81.8%
#9624: fix(memory): resolve QMD search returning empty results [AI-assisted]
by kowshik24 · 2026-02-05
79.7%
#21978: perf: parallelize QMD multi-collection queries
by maximalmargin · 2026-02-20
78.1%
#20085: Fix QMD memory_search empty results when docid key changes
by rylena · 2026-02-18
76.5%
#11364: fix(memory/qmd): prevent cascading failure when query fails or retu...
by blazerui · 2026-02-07
76.1%
#16917: fix(memory): close stale SQLite connection after qmd update
by zerone0x · 2026-02-15
75.5%
#21471: fix: check QMD backend before memory search config
by lbo728 · 2026-02-20
75.0%
#9381: Fix: Allow QMD CLI memory search when scope is restrictive
by vishaltandale00 · 2026-02-05
73.9%