From be70ea96b6b0e4aa9c6c92d2350597eb75e4aa21 Mon Sep 17 00:00:00 2001 From: gustav-fff <286169375+gustav-fff@users.noreply.github.com> Date: Wed, 22 Jul 2026 14:16:42 -0700 Subject: [PATCH] fix(pi-fff): stop reopening main LMDB envs in aux finders (#700) LMDB envs may only be opened once per process. AuxFinderPool was forwarding the main finder's frecencyDbPath / historyDbPath into every aux FileFinder, so the first out-of-workspace search failed with "environment already open in this program". Aux finders are transient and per-search; they run without persistent frecency/history scoring. Closes #700 --- packages/pi-fff/src/aux-finders.ts | 7 +++---- packages/pi-fff/src/index.ts | 2 -- packages/pi-fff/test/aux-pool.test.ts | 26 ++++++++++++++++++++++---- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/packages/pi-fff/src/aux-finders.ts b/packages/pi-fff/src/aux-finders.ts index 6b1fd4713..37bfe23ce 100644 --- a/packages/pi-fff/src/aux-finders.ts +++ b/packages/pi-fff/src/aux-finders.ts @@ -14,8 +14,6 @@ interface AuxPicker { } export interface AuxOpts { - frecencyDbPath?: string; - historyDbPath?: string; enableFsRootScanning: boolean; } @@ -69,10 +67,11 @@ export class AuxFinderPool { } const { FileFinder } = await loadSdk(); + // LMDB env can only be opened once per process; the main finder already + // owns the frecency/history DBs. Aux finders are transient and run without + // persistent scoring — see issue #700. const result = FileFinder.create({ basePath: maybeRoot, - frecencyDbPath: this.opts.frecencyDbPath, - historyDbPath: this.opts.historyDbPath, aiMode: true, enableHomeDirScanning: true, enableFsRootScanning: this.opts.enableFsRootScanning, diff --git a/packages/pi-fff/src/index.ts b/packages/pi-fff/src/index.ts index 649aaca29..764a8312e 100644 --- a/packages/pi-fff/src/index.ts +++ b/packages/pi-fff/src/index.ts @@ -344,8 +344,6 @@ export default function fffExtension(pi: ExtensionAPI) { } let auxPool = new AuxFinderPool({ - frecencyDbPath, - historyDbPath, enableFsRootScanning, }); diff --git a/packages/pi-fff/test/aux-pool.test.ts b/packages/pi-fff/test/aux-pool.test.ts index 6ea03a538..13110f599 100644 --- a/packages/pi-fff/test/aux-pool.test.ts +++ b/packages/pi-fff/test/aux-pool.test.ts @@ -8,6 +8,7 @@ interface MockFinder { } const created: MockFinder[] = []; +const createOptions: Record[] = []; function createMockFinder(basePath: string): MockFinder { const finder: MockFinder = { @@ -24,10 +25,13 @@ function createMockFinder(basePath: string): MockFinder { const finderModule = { FileFinder: { - create: (options: { basePath: string }) => ({ - ok: true, - value: createMockFinder(options.basePath), - }), + create: (options: Record) => { + createOptions.push(options); + return { + ok: true, + value: createMockFinder(options.basePath as string), + }; + }, }, }; @@ -38,6 +42,7 @@ const { AuxFinderPool } = await import("../src/aux-finders"); function makePool() { created.length = 0; + createOptions.length = 0; return new AuxFinderPool({ enableFsRootScanning: false }); } @@ -86,4 +91,17 @@ describe("AuxFinderPool covering reuse", () => { expect(other.root).toBe("/a/b"); expect(created.length).toBe(2); }); + + // Regression for #700: aux finders must not reopen the main frecency/history + // LMDB envs, or heed fails with "environment already open in this program". + test("aux finders are created without frecency/history db paths", async () => { + const pool = makePool(); + await pool.acquire("/a/b/c"); + await pool.acquire("/x/y"); + expect(createOptions.length).toBe(2); + for (const opts of createOptions) { + expect(opts.frecencyDbPath).toBeUndefined(); + expect(opts.historyDbPath).toBeUndefined(); + } + }); });