dmtrKovalenko/fff · error · Error

searchResult.error

Error message

searchResult.error

What it means

The picker's `fileSearch` returns a result object { ok, error?, value? }; the tool throws the error string when `ok` is false. This wraps native file-index search failures — index not ready, destroyed picker, or internal native errors.

Solutions

  1. Wait for initial indexing to finish (scan progress) before searching
  2. Retry the find — transient index states often resolve after the watcher settles
  3. Simplify the query/pattern/exclude combination if the error points at query construction
  4. Rebuild the native binary if errors persist across queries

Example fix

// before
await picker.fileSearch(query, ...) // immediately after startSession, scan incomplete

// after
await fff.waitForScan(); // or retry until index ready
await picker.fileSearch(query, ...)
Defensive patterns

Strategy: retry

Validate before calling

// wait for index readiness if exposed
await fff.waitForScan?.();

Try / catch

try { await findTool.execute(id, params, signal); } catch (e) { if (indexWarmingUp) return retryWithBackoff(); throw e; }

Prevention

When it happens

Trigger: Calling find while the native index is still being built or has been destroyed; internal failure in the native fileSearch implementation; querying with a malformed query built from path+pattern+exclude constraints.

Common situations: Searching immediately after session start before the initial scan populates the index; a picker destroyed by a cwd change mid-search; very large home-dir scans hitting limits.

Related errors


AI-assisted analysis of dmtrKovalenko/fff@7f8537e70f (2026-09-10). Data as JSON: /api/errors/362cc366d5056d65. Report an issue: GitHub.

Appendix: source

Thrown at packages/pi-fff/src/index.ts:1093

      const effectiveLimit = resumed
        ? resumed.pageSize
        : Math.max(1, params.limit ?? DEFAULT_FIND_LIMIT);

      const query = resumed
        ? resumed.query
        : aux && "query" in aux
          ? (aux as { query: string }).query
          : buildQuery(params.path, params.pattern, params.exclude, activeCwd);

      const pattern = resumed ? resumed.pattern : params.pattern;
      const pageIndex = resumed?.nextPageIndex ?? 0;
      const auxRoot = resumed?.auxRoot ?? aux?.root;

      const searchResult = picker.fileSearch(query, {
        pageIndex,
        pageSize: effectiveLimit,
      });
      if (!searchResult.ok) throw new Error(searchResult.error);

      const result = searchResult.value;
      const formatted = formatFindOutput(result, effectiveLimit, pattern);
      let output = formatted.output;

      // Infer hasMore: native fileSearch fills pageSize when more results
      // exist, so if we got a full page AND totalMatched exceeds what we've
      // shown so far there's another page to fetch.
      const shownSoFar = pageIndex * effectiveLimit + result.items.length;
      const hasMore =
        result.items.length >= effectiveLimit && result.totalMatched > shownSoFar;

      const notices: string[] = [];
      if (formatted.weak && formatted.shownCount > 0)
        notices.push(
          `Query "${pattern}" produced only weak scattered fuzzy matches. Output capped at ${formatted.shownCount}/${result.totalMatched}.`,
        );

View on GitHub (pinned to 7f8537e70f)