sharkdp/fd · error · anyhow::Error

Mismatch in exclude patterns

Error message

Mismatch in exclude patterns

What it means

After all --exclude patterns are added, build_overrides calls ignore::OverrideBuilder::build (walk.rs:343); if the compiled override set is internally inconsistent (e.g. mutually contradictory or otherwise unbuildable), fd reports 'Mismatch in exclude patterns'. Unlike the per-pattern error above, this is a failure of the combined set.

Solutions

  1. Reduce the set of --exclude patterns to the minimum and re-add until the conflict reproduces, then rewrite the offending pattern.
  2. Move persistent excludes into a .fdignore / .gitignore file and let fd read them via its ignore machinery instead of many --exclude flags.
  3. Check `fd --help` and the ignore crate docs for glob precedence/negation rules.

Example fix

# before (conflicting excludes)
fd --exclude '*.log' --exclude '!debug.log' .

# after (use a .fdignore file with precedence-aware rules)
echo '*.log' > .fdignore
echo '!debug.log' >> .fdignore
fd .
Defensive patterns

Strategy: validation

Validate before calling

# No cheap pre-check for set-level inconsistency; minimize and test the set.
# Move complex excludes to .fdignore and validate:
fd --exclude p1 --exclude p2 --max-depth 0 . >/dev/null 2>&1 || \
  echo "exclude set rejected" >&2

Prevention

When it happens

Trigger: A combination of --exclude patterns that individually parse but together cannot be compiled by the ignore crate's OverrideBuilder. This is rarer than per-pattern errors and reflects an inconsistency surfaced only at build time.

Common situations: Layering many exclude patterns where one negation/scope rule conflicts with another; upgrading the ignore crate to a version with stricter build validation; complex gitignore-style patterns that interact unexpectedly.

Related errors


AI-assisted analysis of sharkdp/fd@ee20f426dd (2026-08-09). Data as JSON: /api/errors/03f6b4faece9c4f6. Report an issue: GitHub.

Appendix: source

Thrown at src/walk.rs:344

            interrupt_flag,
        }
    }

    fn build_overrides(&self, paths: &[PathBuf]) -> Result<Override> {
        let first_path = &paths[0];
        let config = &self.config;

        let mut builder = OverrideBuilder::new(first_path);

        for pattern in &config.exclude_patterns {
            builder
                .add(pattern)
                .map_err(|e| anyhow!("Malformed exclude pattern: {}", e))?;
        }

        builder
            .build()
            .map_err(|_| anyhow!("Mismatch in exclude patterns"))
    }

    fn build_walker(&self, paths: &[PathBuf]) -> Result<WalkParallel> {
        let first_path = &paths[0];
        let config = &self.config;
        let overrides = self.build_overrides(paths)?;

        let mut builder = WalkBuilder::new(first_path);
        builder
            .hidden(config.ignore_hidden)
            .ignore(config.read_fdignore)
            .parents(config.read_parent_ignore && (config.read_fdignore || config.read_vcsignore))
            .git_ignore(config.read_vcsignore)
            .git_global(config.read_vcsignore)
            .git_exclude(config.read_vcsignore)
            .require_git(config.require_git_to_read_vcsignore)
            .overrides(overrides)
            .follow_links(config.follow_links)

View on GitHub (pinned to ee20f426dd)