{"record":{"id":"e18397aace5c3530","repo":"dmtrKovalenko/fff","slug":"fff-auxiliary-finder-pool-is-not-initialized","errorCode":null,"errorMessage":"FFF auxiliary finder pool is not initialized","messagePattern":"FFF auxiliary finder pool is not initialized","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/pi-fff/src/index.ts","lineNumber":547,"sourceCode":"    if (mainFinder && !mainFinder.isDestroyed) {\n      mainFinder.destroy();\n      mainFinder = null;\n      finderCwd = null;\n    }\n\n    auxPool?.destroy();\n    auxPool = null;\n    pickers = null;\n  }\n\n  async function resolveFinderForPath(\n    pathParam: string | undefined,\n    pattern: string,\n    exclude: string | string[] | undefined,\n  ): Promise<{ finder: FileFinderApi; query: string; root: string } | null> {\n    const route = routePathConstraint(pathParam, activeCwd);\n    if (!route) return null;\n    if (!auxPool) throw new Error(\"FFF auxiliary finder pool is not initialized\");\n    const aux = await auxPool.acquire(route.root);\n    // A broader covering picker may have been reused; rebase the suffix so the\n    // constraint stays relative to the picker's actual root.\n    const rebase = nodePath.relative(aux.root, route.root).replaceAll(nodePath.sep, \"/\");\n    const suffix = [rebase, route.suffix].filter(Boolean).join(\"/\");\n    const query = buildQuery(suffix || undefined, pattern, exclude, aux.root);\n    return { finder: aux.finder, query, root: aux.root };\n  }\n\n  async function getMentionItems(\n    query: string,\n    signal: AbortSignal,\n  ): Promise<AutocompleteItem[]> {\n    if (signal.aborted) return [];\n    const f = await ensureFinder(activeCwd);\n    if (signal.aborted) return [];\n\n    const result = f.mixedSearch(query, { pageSize: MENTION_MAX_RESULTS });","sourceCodeStart":529,"sourceCodeEnd":565,"githubUrl":"https://github.com/dmtrKovalenko/fff/blob/7f8537e70f0ea1210f9acbbfc4640141105cdc78/packages/pi-fff/src/index.ts#L529-L565","documentation":"The auxiliary finder pool (`auxPool`) is null when a path-constrained find/grep needs a scoped picker for a subdirectory. `auxPool` is created alongside the factory in `initializeFinderFactories()` and destroyed in `destroyFinder()`. The guard prevents acquiring pickers from a torn-down pool.","triggerScenarios":"Calling the find or grep tool with a `path` parameter (so `resolveFinderForPath` routes through `auxPool.acquire`) after the extension was shut down, or before session initialization.","commonSituations":"A long-lived agent session emits tool calls after session stop; concurrent sessions where one tears down while the other still queries with path constraints.","solutions":["Re-initialize the extension/session before issuing path-constrained find/grep calls","Avoid sharing tool handles across session lifecycles; create one extension instance per session","Check that session_end/teardown isn't triggered prematurely (e.g. by cwd-change events) while tools are still in flight"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// verify session is active before path-constrained calls\nif (!sessionActive) await startSession();","typeGuard":null,"tryCatchPattern":"try { await grepTool.execute(id, { ...p, path }); } catch (e) { if (String(e).includes('pool is not initialized')) { await startSession(); return grepTool.execute(id, { ...p, path }); } throw e; }","preventionTips":["Avoid path-constrained find/grep calls after session teardown","Re-initialize before resuming work in a new session","Serialize teardown against in-flight tool calls"],"tags":["lifecycle","initialization","null-state"],"backgroundTag":"internal-invariant-violation","analyzedSha":"7f8537e70f0ea1210f9acbbfc4640141105cdc78","analyzedAt":"2026-09-10T07:26:53.407Z","contentChangedAt":"2026-09-10T07:26:53.407Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}