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

  1. To list files under a directory, use a match-all pattern: 'fd . /home/user'.
  2. To match the full path as a regex, enable --full-path: 'fd --full-path /home/user'.
  3. 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

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


AI-assisted analysis of sharkdp/fd@41532d114e (2026-08-06). Data as JSON: /data/errors/f90bc0e7b92d164e.json. Report an issue: GitHub.