From 53c75afbffff7efef22198eff12abbcce8d4cafc Mon Sep 17 00:00:00 2001 From: Jordan Ritter Date: Thu, 7 May 2026 22:08:56 -0700 Subject: [PATCH] Fix walkRoot early return to clean up stale chunks when source directory is missing --- src/__tests__/file-provider.test.ts | 23 +++++++++++++++++++++++ src/indexing/providers/file.ts | 17 ++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/__tests__/file-provider.test.ts b/src/__tests__/file-provider.test.ts index b451949..1b03136 100644 --- a/src/__tests__/file-provider.test.ts +++ b/src/__tests__/file-provider.test.ts @@ -297,6 +297,29 @@ describe("FileDataProvider", () => { // Should still return the current files expect(result.items.length).toBe(3); }); + + it("removes all indexed files when walkRoot does not exist", async () => { + mockGetIndexedItemIds.mockResolvedValueOnce( + new Set(["old-file.md", "another.md"]), + ); + const config = { + ...makeGitConfig(), + path: "/nonexistent/path/that/does/not/exist", + }; + const cloneDir = path.join(tmpDir, "clones"); + const repoDir = path.join(cloneDir, "repo"); + await fs.promises.mkdir(path.join(repoDir, ".git"), { recursive: true }); + + const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); + const provider = new FileDataProvider(config, { cloneDir }); + const result = await provider.fullAcquire(); + + expect(result.items).toEqual([]); + expect(result.removedIds).toContain("old-file.md"); + expect(result.removedIds).toContain("another.md"); + expect(result.removedIds).toHaveLength(2); + warnSpy.mockRestore(); + }); }); // ----------------------------------------------------------------------- diff --git a/src/indexing/providers/file.ts b/src/indexing/providers/file.ts index f24e87a..c3fe70a 100644 --- a/src/indexing/providers/file.ts +++ b/src/indexing/providers/file.ts @@ -90,7 +90,22 @@ export class FileDataProvider implements DataProvider { console.warn( `${this.logPrefix} Walk root not found at ${walkRoot}, skipping`, ); - return { items: [], removedIds: [], stateToken }; + let removedIds: string[] = []; + try { + const indexedPaths = await getIndexedItemIds(this.config.name); + removedIds = [...indexedPaths]; + if (removedIds.length > 0) { + console.log( + `${this.logPrefix} Walk root missing: ${removedIds.length} stale files to remove from index`, + ); + } + } catch (err) { + console.warn( + `${this.logPrefix} Failed to check for stale files:`, + err instanceof Error ? err.message : err, + ); + } + return { items: [], removedIds, stateToken }; } const allFiles = await this.walkFiles(walkRoot);