can1357/oh-my-pi · error
err.to_string() (invalid regex pattern)
Error message
err.to_string() (invalid regex pattern)
What it means
fd compiles include regex patterns with RegexBuilder (case-insensitivity optional); an invalid regular expression produces a regex::Error, surfaced as InvalidInput with err.to_string(). Compilation happens up front, before any filesystem traversal.
Source
Thrown at crates/pi-builtins/src/fd.rs:1235
return Ok(SearchMatcher::Glob(matchers));
}
if cli.fixed_strings {
let patterns = if case_insensitive {
patterns
.into_iter()
.map(|pattern| pattern.to_lowercase())
.collect()
} else {
patterns
};
return Ok(SearchMatcher::Fixed { patterns, case_insensitive });
}
let mut regexes = Vec::with_capacity(patterns.len());
for pattern in patterns {
let regex = RegexBuilder::new(&pattern)
.case_insensitive(case_insensitive)
.build()
.map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err.to_string()))?;
regexes.push(regex);
}
Ok(SearchMatcher::Regex(regexes))
}
fn build_excludes(patterns: &[String]) -> io::Result<Excludes> {
if patterns.is_empty() {
return Ok(Excludes::empty());
}
let mut matchers = Vec::with_capacity(patterns.len());
for pattern in patterns {
let glob = GlobBuilder::new(pattern)
.literal_separator(true)
.build()
.map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err.to_string()))?;
matchers.push(glob.compile_matcher());
}
Ok(Excludes(Arc::new(matchers)))View on GitHub (pinned to 9690622007)
Solutions
- Fix the regex: close all groups, use .* instead of * for globs, and correct {m,n} ranges
- Escape literal metacharacters (. ( ) [ ] { } * + ? ^ $ | \) with backslash or use --fixed-strings
- Validate the pattern with a regex playground or RegexBuilder::new(p).build() before scripting it
Example fix
// before fd 'file(1)' // unescaped parens // after fd 'file\(1\)' // or: fd --fixed-strings 'file(1)'
Defensive patterns
Strategy: validation
Validate before calling
function validRegex(p) { try { new RegExp(p); return true; } catch { return false; } }patterns.forEach(p => { if (!validRegex(p)) throw new Error(`invalid regex: ${p}`); }); Type guard
fn is_regex_error(msg: &str) -> bool { msg.contains("regex parse error") || msg.contains("unrecognized escape") } Try / catch
let regexes = patterns.iter().map(|p| RegexBuilder::new(p).build()).collect::<Result<Vec<_>, _>>().map_err(|e| format!("bad regex: {}", e))?; Prevention
- Escape regex metacharacters when interpolating user input into patterns
- Use --fixed-strings for literal searches instead of escaping by hand
- Test dynamic patterns with RegexBuilder::new(p).build() in unit tests
When it happens
Trigger: `fd '(foo'`, `fd '*x'`, `fd 'a{2,1}'` — unclosed groups, regex metacharacters used as literals, or invalid repetition ranges.
Common situations: Users confusing glob syntax with regex (fnmatch `*` vs regex `.*`), dynamically built patterns from variables, or patterns copied from grep -E with unsupported syntax.
Related errors
- err.to_string() (invalid glob pattern)
- err.to_string() (invalid exclude glob pattern)
- --list-details, --exec, and --exec-batch are not supported b
- positional paths cannot be combined with --search-path
- invalid {} argument: {}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/8c10d03c0b0ed6ba.
Report an issue: GitHub.