astral-sh/ruff · error

Unable to parse filename

Error message

Unable to parse filename

What it means

This is a panic guard on Path::file_name: the code calls path.file_name().expect(...) while matching a file against per-file exclusion patterns, and file_name() returns None only when the path terminates in '..' or is otherwise a nameless terminus (e.g. an empty path or a root-relative path with no file component). In practice every file discovered by the linter has a file name, so this sentinel expect fires only for malformed or synthesized paths reaching iter_matches without a final component.

Source

Thrown at crates/ruff_linter/src/settings/types.rs:867

    pub(crate) fn is_empty(&self) -> bool {
        self.inner.is_empty()
    }
}

impl<T: std::fmt::Debug> CompiledPerFileList<T> {
    /// Return an iterator over the entries in `self` that match the input `path`.
    ///
    /// `debug_label` is used for [`debug!`] messages explaining why certain patterns were matched.
    pub(crate) fn iter_matches<'a, 'p>(
        &'a self,
        path: &'p Path,
        debug_label: &'static str,
    ) -> impl Iterator<Item = &'p T>
    where
        'a: 'p,
    {
        let file_name = path.file_name().expect("Unable to parse filename");
        let basename = Candidate::new(file_name);
        let absolute = Candidate::new(path);
        self.inner.iter().filter_map(move |entry| {
            if entry.basename_matcher.is_match_candidate(&basename) {
                if entry.negated {
                    None
                } else {
                    debug!(
                        "{} for {:?} due to basename match on {:?}: {:?}",
                        debug_label,
                        path,
                        entry.basename_matcher.glob().regex(),
                        entry.data
                    );
                    Some(&entry.data)
                }
            } else if entry.absolute_matcher.is_match_candidate(&absolute) {
                if entry.negated {

View on GitHub (pinned to 26f38c119c)

Solutions

  1. Ensure any programmatically constructed or canonicalized path passed to exclusion matching (e.g. via match_exclusion in add_noqa.rs or analyze_graph.rs) retains a final file component and is not '..', empty, or root-only
  2. Filter out or skip paths where path.file_name() returns None before passing them to iter_matches, instead of relying on the expect to panic
  3. If handling nameless paths is required, replace the expect with a graceful fallback such as treating a missing file name as a non-match for exclusion patterns
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/ruff_linter/src/settings/types.rs:867 when the library encounters an invalid state.

Common situations: See trigger scenarios.

Understand the failure class


AI-assisted analysis of astral-sh/ruff@26f38c119c (2026-09-05). Data as JSON: /api/errors/da60319f6480e9c1. Report an issue: GitHub.