dmtrKovalenko/fff · error · Error

grepResult.error

Error message

grepResult.error

What it means

The underlying picker's grep operation returns a result object of shape { ok, error?, value? }; when `ok` is false the tool rethrows the contained error string. This surfaces native (Rust/ripgrep-style) grep failures — bad regex, IO errors, internal panics — as thrown exceptions.

Solutions

  1. Read the thrown message: if it mentions regex, fix the pattern (escape metacharacters or use literal constraints)
  2. Verify the searched path exists and is readable
  3. Catch the error and fall back to a simpler pattern or the find tool
  4. Rebuild/update the native fff binary if the error indicates an internal/FFI failure

Example fix

// before
pattern: "foo("

// after
pattern: "foo\\(" // escape regex metacharacters, or use multiGrep with literal patterns
Defensive patterns

Strategy: try-catch

Validate before calling

// validate regex before calling
new RegExp(pattern); // throws locally on invalid pattern

Try / catch

try { await grepTool.execute(id, params, signal); } catch (e) { if (String(e).match(/regex|pattern/i)) return simplifiedGrep(params); throw e; }

Prevention

When it happens

Trigger: Calling grep with an invalid regex pattern; the picker's file walker failing on unreadable paths; an internal error inside the native search binary; timeout/abort surfacing inside the native call.

Common situations: Patterns containing unbalanced parens/brackets or regex metacharacters the engine rejects; searching directories with permission problems; native binary version mismatch.

Related errors


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

Appendix: source

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

      }

      // caseSensitive override flips smartCase off; omitting it keeps smart-case
      // (case-insensitive when pattern is all lowercase).
      const smartCase = params.caseSensitive !== true;

      const grepResult = picker.grep(query, {
        mode,
        smartCase,
        maxMatchesPerFile: GREP_MAX_MATCHES_PER_FILE,
        pageSize,
        cursor: (params.cursor ? getCursor(params.cursor) : null) ?? null,
        beforeContext: context,
        afterContext: context,
        classifyDefinitions: true,
        timeBudgetMs: GREP_TIME_BUDGET_MS,
      });

      if (!grepResult.ok) throw new Error(grepResult.error);

      let result = grepResult.value;
      let fuzzyNotice: string | null = null;

      // if we hit the timeout do not run the fuzzy fallback
      // cause it will only consumer more time
      if (
        result.items.length === 0 &&
        !result.nextCursor &&
        !params.cursor &&
        mode !== "regex"
      ) {
        // When the caller pinned a specific file (path has an extension), the
        // fuzzy fallback broadens across the whole picker — the file may just
        // be misnamed. For directory constraints (or no path), we keep the
        // constrained query so the fallback does not leak matches from
        // excluded / out-of-scope directories.
        const lastSeg = params.path?.split(/[\\/]/).pop() ?? "";

View on GitHub (pinned to 7f8537e70f)