neoclide/coc.nvim · error
Regex is too complex for the JavaScript search fallback; ins
Error message
Regex is too complex for the JavaScript search fallback; install ripgrep to use it safely
What it means
When ripgrep is not used, workspace search falls back to a pure-JavaScript matcher. Some regex constructs (lookarounds `(?=`, `(?!`, `(?<`, nested quantifiers like `(a+)+`) risk catastrophic backtracking in JS, so `searchWithJs` refuses them and asks the user to install ripgrep instead.
Source
Thrown at src/mcp/tools/workspace.ts:118
}
export function escapeRegExp(text: string): string {
return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
}
function unsafeFallbackRegex(pattern: string): boolean {
// JavaScript RegExp has no execution timeout. Keep the no-ripgrep fallback
// to expressions without the constructs most commonly responsible for
// catastrophic backtracking; ripgrep remains the unrestricted regex path.
return pattern.length > 1000
|| /\\[1-9]/.test(pattern)
|| /\(\?[=!<]/.test(pattern)
|| /\([^)]*[+*{][^)]*\)\s*(?:[+*?]|\{)/.test(pattern)
}
export async function searchWithJs(pattern: string, args: any, root: string, maxResults: number): Promise<SearchMatch[]> {
if (args.regex === true && unsafeFallbackRegex(pattern)) {
throw new Error('Regex is too complex for the JavaScript search fallback; install ripgrep to use it safely')
}
let include = new RelativePatternImpl(URI.file(root), typeof args.include === 'string' && args.include ? args.include : '**/*')
let uris = await workspace.findFiles(include, args.exclude || null, 500)
// One (first) match per line, searched from the start of every line: the
// global flag would carry lastIndex across lines and skip matches.
let flags = args.caseSensitive === true ? '' : 'i'
let source = args.regex === true ? pattern : escapeRegExp(pattern)
let re: RegExp
try {
re = new RegExp(source, flags)
} catch (e) {
throw new Error(`Invalid regex: ${e instanceof Error ? e.message : String(e)}`)
}
let results: SearchMatch[] = []
for (let uri of uris) {
if (results.length >= maxResults) break
let filepath = uri.fsPath
if (checkPath(filepath)) continueView on GitHub (pinned to 50e974d969)
Solutions
- Install ripgrep so searches run through the native engine (`rg` on PATH)
- Rewrite the pattern without lookarounds or nested quantifiers (use character classes or restructure the expression)
- Run the search with `regex: false` (literal search) if the exact regex features aren't needed
- Split a complex pattern into multiple simpler searches
Example fix
// before
{ regex: true, query: "(?<=@)\w+" } // lookbehind, unsafe fallback
// after
{ regex: true, query: "@\w+" } // or install ripgrep Defensive patterns
Strategy: fallback
Validate before calling
function unsafeFallbackRegex(p: string): boolean {
return /\(\?[=!<]/.test(p) || /\([^)]*[+*{][^)]*\)\s*(?:[+*?]|\{)/.test(p)
}
if (args.regex === true && unsafeFallbackRegex(args.query) && !hasRipgrep()) {
args.regex = false // literal search instead
} Try / catch
try {
matches = await searchWithJs(pattern, args, root, max)
} catch (e) {
if (/too complex for the JavaScript search fallback/.test(e.message)) {
matches = await searchWithJs(escapeRegExp(pattern), { ...args, regex: false }, root, max)
} else throw e
} Prevention
- Install ripgrep so the native engine handles all regexes
- Prefer patterns without lookarounds/nested quantifiers when ripgrep may be absent
- Fall back to literal (regex:false) search on this error
- Test user-supplied regexes against unsafeFallbackRegex before invoking search
When it happens
Trigger: Calling the workspace search tool with `regex: true` and a pattern containing lookarounds or nested quantifiers (detected by `unsafeFallbackRegex`) while ripgrep is not available on the system.
Common situations: Environment without ripgrep installed (not on PATH); patterns ported from ripgrep/PCRE habits that use lookahead; a user-supplied search query that happens to include nested repetition.
Related errors
- pattern \z not supported
- pattern (?s) not supported
- pattern (?x) not supported
- pattern \n not supported
- pattern (?id/name)yes-pattern|no-pattern not supported
AI-assisted analysis of neoclide/coc.nvim@50e974d969 (2026-08-31).
Data as JSON: /api/errors/ddaa968ac239c17d.
Report an issue: GitHub.