sharkdp/fd · error · anyhow::Error
The search pattern '{pattern}' contains a path-separation ch
Error message
The search pattern '{pattern}' contains a path-separation character and will not lead to any search results.
If you want to search for all files inside the '{pattern}' directory, use a match-all pattern:
fd . '{pattern}'
Instead, if you want your pattern to match the full file path, use:
fd --full-path '{pattern}' What it means
Thrown by ensure_single_search_pattern_is_not_a_path in src/main.rs:204. Without --full-path, fd matches the pattern against the file name only, so any '/' in the pattern (or, on Windows, a '\' naming an existing directory) can never match. Rather than return zero results silently, fd aborts with guidance. This applies to the primary pattern and every --and pattern.
Source
Thrown at src/main.rs:204
// Start with the cheap check: '/' is always a path separator, including on
// Windows, and has no regex meaning, so flagging it is safe and catches the
// Linux/macOS mistake of pasting a full path as the pattern.
#[cfg_attr(not(windows), allow(unused_mut))]
let mut should_warn = pattern.contains('/');
// On Windows we additionally accept the native `\` separator, but only when
// the pattern actually resolves to an existing directory - `\` is also the
// regex escape char there, so valid patterns like `\Ac` or `\d+` must still
// run. The is_dir syscall is only needed when `should_warn` is still false,
// so short-circuit via `||` to avoid the stat call on the happy path.
#[cfg(windows)]
{
should_warn = should_warn
|| (pattern.contains(std::path::MAIN_SEPARATOR) && Path::new(pattern).is_dir());
}
if should_warn {
Err(anyhow!(
"The search pattern '{pattern}' contains a path-separation character \
and will not lead to any search results.\n\n\
If you want to search for all files inside the '{pattern}' directory, use a match-all pattern:\n\n \
fd . '{pattern}'\n\n\
Instead, if you want your pattern to match the full file path, use:\n\n \
fd --full-path '{pattern}'",
pattern = pattern,
))
} else {
Ok(())
}
}
fn build_pattern_regex(pattern: &str, opts: &Opts) -> Result<String> {
Ok(if opts.glob && !pattern.is_empty() {
let glob = GlobBuilder::new(pattern).literal_separator(true).build()?;
glob.regex().to_owned()
} else if opts.exact {View on GitHub (pinned to 41532d114e)
Solutions
- To list files under a directory, use a match-all pattern: 'fd . /home/user'.
- To match the full path as a regex, enable --full-path: 'fd --full-path /home/user'.
- Quote the literal path and add --fixed-strings --full-path if you want a plain substring over the whole path.
Example fix
// before fd src/foo.rs // after fd --full-path 'src/foo.rs'
Defensive patterns
Strategy: validation
Validate before calling
# if the pattern contains a path separator, switch modes explicitly if printf '%s' "$PAT" | grep -Eq '[/\\]'; then fd --full-path --fixed-strings "$PAT" "$@" else fd "$PAT" "$@" fi
Type guard
fn looks_like_path(s: &str) -> bool {
s.contains('/')
} Prevention
- If you want to list files under a directory, use 'fd . <dir>'.
- If you want full-path matching, always pass --full-path.
- Treat the first positional as a regex against the file name, not a path.
When it happens
Trigger: Running 'fd /home/user', 'fd src/foo.rs', or on Windows 'fd C:\Users' (when that path is an existing dir), all without --full-path.
Common situations: Pasting a full path expecting substring matching; muscle memory from 'find /path'; treating the first positional as a path rather than a regex.
Related errors
- A path separator must be exactly one byte, but the given sep
- The pattern(s) seems to only match files with a leading dot,
- {} Note: You can search for literal substrings with '--fixe
- Unable to get shell from environment
- more than one ':' present in owner string '{}'. See 'fd --he
AI-assisted analysis of sharkdp/fd@41532d114e (2026-08-06).
Data as JSON: /data/errors/f90bc0e7b92d164e.json.
Report an issue: GitHub.