← Back to PRs

#20966: fix(memory/qmd): migrate orphaned unscoped collections on upgrade

by marcodelpin open 2026-02-19 14:04 View on GitHub →
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