can1357/oh-my-pi · error

err.to_string() (invalid glob pattern)

Error message

err.to_string() (invalid glob pattern)

What it means

fd compiles each include glob pattern with the glob crate's GlobBuilder (literal_separator enabled, optional case-insensitivity); a syntactically invalid pattern yields a PatternError, which fd converts to InvalidInput with the parser's message via err.to_string().

Source

Thrown at crates/pi-builtins/src/fd.rs:1214

	}
	let case_insensitive = if cli.ignore_case {
		true
	} else if cli.case_sensitive {
		false
	} else {
		!patterns
			.iter()
			.any(|pattern| pattern.chars().any(char::is_uppercase))
	};

	if cli.glob {
		let mut matchers = Vec::with_capacity(patterns.len());
		for pattern in patterns {
			let glob = GlobBuilder::new(&pattern)
				.literal_separator(true)
				.case_insensitive(case_insensitive)
				.build()
				.map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err.to_string()))?;
			matchers.push(glob.compile_matcher());
		}
		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)

View on GitHub (pinned to 9690622007)

Solutions

  1. Fix the glob syntax: balance [] and {}, and escape literal specials with backslash
  2. Quote the pattern in the shell so brackets/braces survive (single quotes are safest)
  3. Validate the pattern by compiling it with a glob tester before embedding in scripts
  4. If you meant a plain substring, use --fixed-strings instead of --glob

Example fix

// before
fd --glob 'src/[[:num]]'    // malformed class
// after
fd --glob 'src/[0-9]*'
Defensive patterns

Strategy: validation

Validate before calling

use glob::Pattern;fn valid_glob(p: &str) -> bool { Pattern::new(p).is_ok() }let bad: Vec<_> = patterns.iter().filter(|p| !valid_glob(p)).collect();if !bad.is_empty() { return Err(format!("invalid glob(s): {:?}", bad)); }

Type guard

fn is_glob_error(msg: &str) -> bool { msg.contains("error parsing glob") || msg.contains("PatternError") }

Try / catch

let matchers: Vec<_> = patterns.iter().map(|p| GlobBuilder::new(p).literal_separator(true).build()).collect::<Result<_, _>>().map_err(|e| format!("bad glob: {}", e))?;

Prevention

When it happens

Trigger: `fd --glob '['` or `--glob 'a{b'` — unbalanced brackets/braces, dangling escape like `foo\`, or an empty/invalid alternation in the glob.

Common situations: Hand-written globs with unescaped `[` (e.g. matching literal brackets in filenames), patterns built by string concatenation in scripts, or patterns quoted incorrectly so the shell strips characters.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/3bb6e388c2aca8bc. Report an issue: GitHub.