dmtrKovalenko/fff · error · Error
patterns array must have at least 1 element
Error message
patterns array must have at least 1 element
What it means
multiGrep requires at least one pattern; the tool validates `params.patterns?.length` and throws when the array is missing, null, or empty. This is an explicit input validation guard before hitting the native grep.
Solutions
- Pass at least one literal pattern in the patterns array
- If all patterns were filtered out, skip the call entirely instead of invoking with []
- Use the single-pattern grep tool when you only have one pattern
- Validate the array length before calling when patterns are generated dynamically
Example fix
// before
await multiGrep.execute(id, { patterns: filteredPatterns }); // [] when nothing matched
// after
if (filteredPatterns.length > 0) {
await multiGrep.execute(id, { patterns: filteredPatterns });
} Defensive patterns
Strategy: validation
Validate before calling
if (!Array.isArray(patterns) || patterns.length === 0) throw new Error('patterns must contain at least 1 element'); Type guard
const hasPatterns = (p: unknown): p is { patterns: [string, ...string[]] } =>
typeof p === 'object' && p !== null && Array.isArray((p as any).patterns) && (p as any).patterns.length > 0; Try / catch
try { await multiGrepTool.execute(id, params, signal); } catch (e) { if (String(e).includes('at least 1 element')) return null; throw e; } Prevention
- Check patterns.length before calling
- Fall back to single-pattern grep when only one pattern exists
- Skip the call entirely when generated pattern lists end up empty
When it happens
Trigger: Calling multiGrep with `patterns: []`, with `patterns` omitted, or with `patterns: null` (e.g. spread-built param objects that collapsed to empty).
Common situations: Dynamically generating pattern lists where all candidates were filtered out; LLM/agent emitting an empty array; template code leaving the patterns slot unfilled.
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
- patterns array must have at least 1 element
- grepResult.error
- Path constraint must be relative to the workspace
- Query is null or invalid UTF-8
- File path is null or invalid UTF-8
AI-assisted analysis of dmtrKovalenko/fff@7f8537e70f (2026-09-10).
Data as JSON: /api/errors/46d3a48015ebdb09.
Report an issue: GitHub.
Appendix: source
Thrown at packages/pi-fff/src/index.ts:1199
),
cursor: Type.Optional(Type.String({ description: "Pagination cursor" })),
});
queueTool(() => toolNames.multiGrep, {
description:
"Search file contents for ANY of multiple literal patterns (OR, SIMD Aho-Corasick). Faster than regex alternation.",
promptSnippet: "Multi-pattern OR content search",
promptGuidelines: (names) => [
`${names.multiGrep}: use when searching for several identifiers at once.`,
`${names.multiGrep}: include all naming-convention variants (snake/camel/Pascal).`,
`${names.multiGrep}: patterns are literal. Use constraints for file filters.`,
],
parameters: multiGrepSchema,
async execute(_toolCallId, params, signal) {
if (signal?.aborted) throw new Error("Operation aborted");
if (!params.patterns?.length)
throw new Error("patterns array must have at least 1 element");
const f = await ensureFinder(activeCwd);
const effectiveLimit = Math.max(1, params.limit ?? DEFAULT_GREP_LIMIT);
const pageSize = Math.min(effectiveLimit, GREP_PAGE_SIZE_MAX);
const context = clampContext(params.context);
const grepResult = f.multiGrep({
patterns: params.patterns,
constraints: params.constraints,
maxMatchesPerFile: GREP_MAX_MATCHES_PER_FILE,
pageSize,
smartCase: true,
cursor: (params.cursor ? getCursor(params.cursor) : null) ?? null,
beforeContext: context,
afterContext: context,
});
if (!grepResult.ok) throw new Error(grepResult.error);View on GitHub (pinned to 7f8537e70f)