#20966: fix(memory/qmd): migrate orphaned unscoped collections on upgrade
size: S
## Summary
Fixes #20727 — `memory_search` returns empty results after upgrading because qmd collections created before per-agent scoping (b32ae6fa0) are never migrated.
### Root Cause
Commit b32ae6fa0 introduced agent-scoped collection names (`memory-root-main` instead of `memory-root`). On upgrade:
1. `ensureCollections()` lists existing qmd collections → finds `memory-root`, `memory-alt`, `memory-dir`
2. Looks for scoped names `memory-root-main` etc. → not found
3. Tries to add `memory-root-main` → qmd rejects it (same path already monitored by `memory-root`)
4. Search passes `-c memory-root-main` → collection not found → empty results
### Fix
Added a migration step in `ensureCollections()` that runs before the main collection setup loop:
- For each expected scoped collection name (e.g. `memory-root-main`), compute the old unscoped name (`memory-root`)
- If the unscoped name exists in qmd but the scoped name does not, remove the unscoped collection
- The subsequent `addCollection` call then succeeds with the new scoped name
The migration is idempotent — it only runs when orphaned unscoped collections are detected and skips entirely when collections are already scoped.
### Files Changed (2)
- `src/memory/qmd-manager.ts` — migration loop in `ensureCollections()` (+23 lines)
- `src/memory/qmd-manager.test.ts` — 2 new tests: orphaned collection migration + already-scoped skip (+104 lines)
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR fixes a critical bug where `memory_search` returns empty results after upgrading from pre-agent-scoped collection names. The migration adds a cleanup step in `ensureCollections()` that removes orphaned unscoped collections (e.g., `memory-root`) when the corresponding scoped collection (e.g., `memory-root-main`) is expected but doesn't exist yet. This allows qmd to accept the new scoped collection names without path conflicts.
Key changes:
- Migration loop in `ensureCollections()` removes orphaned unscoped collections before the main setup
- Migration is idempotent and only runs when unscoped collections exist without their scoped counterparts
- Two comprehensive tests cover both migration scenarios (orphaned collections + already-scoped)
- Error handling accounts for missing collections and logs warnings for other failures
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk
- The migration logic is sound, idempotent, and well-tested. It only removes collections when it's safe to do so (unscoped exists, scoped doesn't exist), includes proper error handling, and has comprehensive test coverage for both migration and no-op scenarios. The fix directly addresses the reported issue without introducing breaking changes.
- No files require special attention
<sub>Last reviewed commit: ecc78f1</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
---
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Testing: fully tested (automated + manual verification)
I understand and can explain all changes in this PR.
Most Similar PRs
#22937: fix: remove legacy unsuffixed QMD collections on upgrade
by sud0n1m-ziggy · 2026-02-21
90.4%
#16968: fix(qmd): per-collection search to prevent large collections drowni...
by ProgramCaiCai · 2026-02-15
84.4%
#21868: fix: qmd search/vsearch silently return empty with multiple -c coll...
by jacksclaw · 2026-02-20
81.8%
#21471: fix: check QMD backend before memory search config
by lbo728 · 2026-02-20
77.6%
#9624: fix(memory): resolve QMD search returning empty results [AI-assisted]
by kowshik24 · 2026-02-05
77.6%
#19022: memory: support per-agent QMD collection paths
by Whoaa512 · 2026-02-17
76.9%
#20085: Fix QMD memory_search empty results when docid key changes
by rylena · 2026-02-18
76.7%
#17657: fix: clear QMD manager cache on in-process restart (SIGUSR1)
by IrriVisionTechnologies · 2026-02-16
76.2%
#9381: Fix: Allow QMD CLI memory search when scope is restrictive
by vishaltandale00 · 2026-02-05
75.7%
#9149: Fix: Allow QMD backend to work without OpenAI auth
by vishaltandale00 · 2026-02-04
75.1%