{"record":{"id":"b49b53c1cdf33f99","repo":"dmtrKovalenko/fff","slug":"patterns-array-must-have-at-least-1-element-b49b53","errorCode":null,"errorMessage":"patterns array must have at least 1 element","messagePattern":"patterns array must have at least 1 element","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/fff-bun/src/finder.ts","lineNumber":413,"sourceCode":"   *\n   * @example\n   * ```typescript\n   * const result = finder.multiGrep({\n   *   patterns: [\"VideoFrame\", \"video_frame\", \"PreloadedImage\"],\n   * });\n   * if (result.ok) {\n   *   for (const match of result.value.items) {\n   *     console.log(`${match.relativePath}:${match.lineNumber}: ${match.lineContent}`);\n   *   }\n   * }\n   * ```\n   */\n  multiGrep(options: MultiGrepOptions): Result<GrepResult> {\n    const guard = this.ensureAlive();\n    if (!guard.ok) return guard;\n\n    if (!options.patterns || options.patterns.length === 0) {\n      return err(\"patterns array must have at least 1 element\");\n    }\n\n    return ffiMultiGrep(\n      guard.value,\n      options.patterns.join(\"\\n\"),\n      options.constraints ?? \"\",\n      options.maxFileSize ?? 0,\n      options.maxMatchesPerFile ?? 0,\n      options.smartCase ?? true,\n      options.cursor?._offset ?? 0,\n      options.pageSize ?? 0,\n      options.timeBudgetMs ?? 0,\n      options.enforceTimeBudget ?? false,\n      options.beforeContext ?? 0,\n      options.afterContext ?? 0,\n      options.classifyDefinitions ?? false,\n    );\n  }","sourceCodeStart":395,"sourceCodeEnd":431,"githubUrl":"https://github.com/dmtrKovalenko/fff/blob/7f8537e70f0ea1210f9acbbfc4640141105cdc78/packages/fff-bun/src/finder.ts#L395-L431","documentation":"multiGrep validates that the patterns option is a non-empty array before crossing the FFI boundary, because the Rust side expects at least one newline-joined pattern. An empty or missing patterns array would produce a useless or unsafe call into the native library, so it is rejected in JS with this error.","triggerScenarios":"Calling finder.multiGrep() with no options.patterns, with patterns: [], or with patterns left undefined after building options dynamically.","commonSituations":"Building the pattern list programmatically from user input or config where filtering removed all patterns; forgetting to default to a fallback pattern list.","solutions":["Check options.patterns before calling and ensure it contains at least one non-empty pattern","Skip the multiGrep call entirely (or return an empty result) when the pattern list is empty","Add a fallback default pattern when the caller's list filters down to zero"],"exampleFix":"// before\nfinder.multiGrep({ patterns: myPatterns, constraints: '' });\n// after\nif (!myPatterns.length) return;\nfinder.multiGrep({ patterns: myPatterns.length ? myPatterns : ['*'], constraints: '' });","handlingStrategy":"validation","validationCode":"if (!Array.isArray(patterns) || patterns.length === 0) throw new Error('multiGrep needs at least 1 pattern');","typeGuard":"function hasPatterns(o) { return Array.isArray(o?.patterns) && o.patterns.length > 0; }","tryCatchPattern":"try { finder.multiGrep(opts); } catch (e) { if (String(e).includes('patterns array')) { /* recover: use fallback pattern or skip */ } }","preventionTips":["Default pattern lists to a non-empty fallback","Filter patterns only after checking the filtered result is non-empty","Unit-test option builders for the empty case"],"tags":["validation","bun","ffi"],"backgroundTag":"empty-required-field","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"}