dmtrKovalenko/fff · error

patterns array must have at least 1 element

Error message

patterns array must have at least 1 element

What it means

multiGrep requires a non-empty patterns array because patterns are joined with newlines and passed to the native multi-pattern grep. An empty array would produce an empty pattern string and a meaningless native call, so the method rejects it up front with this error.

Solutions

  1. Check patterns.length > 0 before calling multiGrep and skip the call (return an empty GrepResult) when empty.
  2. Fall back to a single-pattern grep when only one pattern is supplied.
  3. Validate MultiGrepOptions at the API boundary so empty pattern lists never reach the finder.
  4. If an empty selection is valid in your app, treat it as a no-op rather than an error.

Example fix

// before
const res = finder.multiGrep({ patterns: selectedTags, constraints });
// after
if (selectedTags.length === 0) return { matches: [], truncated: false };
const res = finder.multiGrep({ patterns: selectedTags, constraints });
Defensive patterns

Strategy: validation

Validate before calling

function canMultiGrep(o?: MultiGrepOptions): boolean {
  return Array.isArray(o?.patterns) && o.patterns.length > 0;
}

Type guard

function hasPatterns(o: MultiGrepOptions): o is MultiGrepOptions & { patterns: [string, ...string[]] } {
  return Array.isArray(o.patterns) && o.patterns.length > 0;
}

Try / catch

const res = finder.multiGrep(opts);
if (!res.ok && /at least 1 element/.test(res.error)) {
  return emptyGrepResult(); // treat as no-op
}

Prevention

When it happens

Trigger: Calling finder.multiGrep({ patterns: [] }) or multiGrep({}) (patterns undefined); building the pattern list dynamically (e.g. from user-selected tags) and passing the result when nothing was selected.

Common situations: UI where the user deselects all search terms before running; refactoring code that used single-pattern grep and forgot the array must contain at least one entry; deserialized options where the patterns field was dropped.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at packages/fff-node/src/finder.ts:419

   *
   * @example
   * ```typescript
   * const result = finder.multiGrep({
   *   patterns: ["VideoFrame", "video_frame", "PreloadedImage"],
   * });
   * if (result.ok) {
   *   for (const match of result.value.items) {
   *     console.log(`${match.relativePath}:${match.lineNumber}: ${match.lineContent}`);
   *   }
   * }
   * ```
   */
  multiGrep(options: MultiGrepOptions): Result<GrepResult> {
    const guard = this.ensureAlive();
    if (!guard.ok) return guard;

    if (!options.patterns || options.patterns.length === 0) {
      return err("patterns array must have at least 1 element");
    }

    return ffiMultiGrep(
      guard.value,
      options.patterns.join("\n"),
      options.constraints ?? "",
      options.maxFileSize ?? 0,
      options.maxMatchesPerFile ?? 0,
      options.smartCase ?? true,
      options.cursor?._offset ?? 0,
      options.pageSize ?? 0,
      options.timeBudgetMs ?? 0,
      options.enforceTimeBudget ?? false,
      options.beforeContext ?? 0,
      options.afterContext ?? 0,
      options.classifyDefinitions ?? false,
    );
  }

View on GitHub (pinned to 7f8537e70f)