helix-editor/helix · warning
Failed to compile regex
Error message
Failed to compile regex
What it means
:global-search builds its matcher with RegexMatcherBuilder (the regex crate, smart-case and multi-line enabled). Queries that are not valid regex — unbalanced parens/brackets, dangling or reversed quantifiers ('*x', 'a{2,1}'), or constructs regex does not support like look-around and backreferences — fail to compile; the picker shows 'Failed to compile regex' and logs the underlying error at info level. On the next keystroke a successful compile clears the statusline error.
Source
Thrown at helix-term/src/commands.rs:2637
let documents: Vec<_> = editor
.documents()
.map(|doc| (doc.path().map(ToOwned::to_owned), doc.text().to_owned()))
.collect();
let matcher = match RegexMatcherBuilder::new()
.case_smart(config.smart_case)
.multi_line(true)
.build(query)
{
Ok(matcher) => {
// Clear any "Failed to compile regex" errors out of the statusline.
editor.clear_status();
matcher
}
Err(err) => {
log::info!("Failed to compile search pattern in global search: {}", err);
return async { Err(anyhow::anyhow!("Failed to compile regex")) }.boxed();
}
};
let dedup_symlinks = config.file_picker_config.deduplicate_links;
let absolute_root = search_root
.canonicalize()
.unwrap_or_else(|_| search_root.clone());
let injector = injector.clone();
async move {
let searcher = SearcherBuilder::new()
.binary_detection(BinaryDetection::quit(b'\x00'))
.multi_line(true)
.build();
WalkBuilder::new(search_root)
.hidden(config.file_picker_config.hidden)
.parents(config.file_picker_config.parents)
.ignore(config.file_picker_config.ignore)View on GitHub (pinned to 079a789e8c)
Solutions
- Escape metacharacters with backslashes: 'foo\(bar\)' instead of 'foo(bar)'.
- Drop unsupported constructs (look-around, backreferences) — the regex crate cannot compile them; reformulate with classes/alternation.
- For pure literal search, escape every one of . * + ? ( ) [ ] { } | ^ $ \ or start from a metacharacter-free substring.
Example fix
# before: unbalanced group foo(bar # after foo\(bar\)
Defensive patterns
Strategy: validation
Validate before calling
// gate the search on the same syntax the matcher uses
if regex::Regex::new(query).is_ok() {
// safe to feed :global-search's dynamic query
} Type guard
fn is_valid_search_regex(q: &str) -> bool {
regex::Regex::new(q).is_ok()
} Prevention
- Escape metacharacters when searching literals; the pattern field is always a regex.
- Remember regex (and thus helix search) has no look-around or backreferences.
When it happens
Trigger: Typing '(' alone, '(?=foo)', '*bar', 'a{2,1}', or a literal string containing metacharacters like 'f(x)+' or 'C++(' into the global-search prompt while it dynamically re-runs.
Common situations: Searching literal text full of regex metacharacters (code snippets, 'foo(bar)', 'a.b*c'); PCRE habits (look-ahead/behind, backreferences) ported from grep -P or other editors; partially typed patterns in the dynamic query.
Related errors
AI-assisted analysis of helix-editor/helix@079a789e8c (2026-08-16).
Data as JSON: /api/errors/6e2582b343282937.
Report an issue: GitHub.