sharkdp/fd · error · anyhow::Error
A path separator must be exactly one byte, but the given…
Error message
A path separator must be exactly one byte, but the given separator is {} bytes: '{}'.
In some shells on Windows, '/' is automatically expanded. Try to use '//' instead. What it means
check_path_separator_length (main.rs:234) validates a user-supplied --path-separator on Windows: it must be exactly one byte. Multi-byte values are rejected because fd builds internal path display using byte-level joins and because some Windows shells (MSYS2/Cygwin/PowerShell) auto-expand a lone '/' into a path, prompting the hint to use '//'. Only enforced on Windows (cfg!(windows)).
Solutions
- Use a single-byte separator: `fd --path-separator \` or omit the flag to use the default.
- If your shell expands '/', quote the argument or use the native '\' separator on Windows.
- Avoid the flag entirely if you just want default behavior.
Example fix
# before (Windows, '//') fd --path-separator // foo # after (single byte) fd --path-separator \\ foo
Defensive patterns
Strategy: validation
Validate before calling
validate_sep() {
local s="$1"
# Windows: must be exactly one byte
if [ ${#s} -eq 1 ]; then
fd --path-separator "$s" .
else
echo "separator must be one byte" >&2; exit 1
fi
} Prevention
- On Windows, prefer the native '\' separator or omit the flag.
- Quote shell arguments to prevent '/' auto-expansion in MSYS2/PowerShell.
- Avoid Unicode separators; fd expects a single byte.
When it happens
Trigger: On Windows, running `fd --path-separator //` or any multi-character/-byte value. The (true, Some(sep)) arm with sep.len() > 1 fires. Note this is a Windows-only guard; Unix passes the (false, _) arm.
Common situations: MSYS2/Git-Bash/PowerShell mangling a single '/' into a Windows root path, leading users to type '//' which then exceeds one byte; passing a Unicode separator character.
Related errors
- 'fd --list-details' is not supported on Windows unless GNU…
- The search pattern ' ' contains a path-separation character…
- Could not retrieve current directory (has it been deleted?).
- 'fd --list-details' is not supported on this platform.
- ' ' is not a valid date or duration. See 'fd --help'.
AI-assisted analysis of sharkdp/fd@ee20f426dd (2026-08-09).
Data as JSON: /api/errors/75aebac43011389c.
Report an issue: GitHub.
Appendix: source
Thrown at src/main.rs:236
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 {
// Anchor the escaped pattern so the full filename (or path) must match exactly.
// Literal. No substring matching.
format!("^{}$", regex::escape(pattern))
} else if opts.fixed_strings {
// Treat pattern as literal string if '--fixed-strings' is used
regex::escape(pattern)
} else {
String::from(pattern)
})
}
fn check_path_separator_length(path_separator: Option<&str>) -> Result<()> {
match (cfg!(windows), path_separator) {
(true, Some(sep)) if sep.len() > 1 => Err(anyhow!(
"A path separator must be exactly one byte, but \
the given separator is {} bytes: '{}'.\n\
In some shells on Windows, '/' is automatically \
expanded. Try to use '//' instead.",
sep.len(),
sep
)),
_ => Ok(()),
}
}
fn construct_config(mut opts: Opts, pattern_regexps: &[String]) -> Result<Config> {
// The search will be case-sensitive if the command line flag is set or
// if any of the patterns has an uppercase character (smart case).
let case_sensitive = !opts.ignore_case
&& (opts.case_sensitive
|| pattern_regexps
.iter()View on GitHub (pinned to ee20f426dd)