astral-sh/ruff · error

Expected <FilePattern>:<RuleCode> pattern

Error message

Expected <FilePattern>:<RuleCode> pattern

What it means

Ruff parses CLI values for --per-file-ignores / --extend-per-file-ignores as PatternPrefixPair, which requires exactly one colon separating a file glob from a rule selector. The string given did not split into exactly two ':'-delimited tokens, so Ruff rejects it before reading any configuration. This is purely a command-line argument format error.

Source

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

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PatternPrefixPair {
    pub pattern: String,
    pub prefix: UnresolvedRuleSelector,
}

impl PatternPrefixPair {
    const EXPECTED_PATTERN: &'static str = "<FilePattern>:<RuleCode> pattern";
}

impl FromStr for PatternPrefixPair {
    type Err = anyhow::Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let (pattern_str, code_string) = {
            let tokens = s.split(':').collect::<Vec<_>>();
            if tokens.len() != 2 {
                bail!("Expected {}", Self::EXPECTED_PATTERN);
            }
            (tokens[0].trim(), tokens[1].trim())
        };
        let pattern = pattern_str.into();
        let prefix = UnresolvedRuleSelector::cli(code_string);
        Ok(Self { pattern, prefix })
    }
}

#[derive(
    Clone,
    Copy,
    Debug,
    PartialOrd,
    Ord,
    PartialEq,
    Eq,
    Default,

View on GitHub (pinned to d1087a4b9e)

Solutions

  1. Rewrite the value as '<FilePattern>:<RuleCode>', e.g. --per-file-ignores 'src/legacy/*.py:E501'
  2. Use a comma to pass multiple pairs: --per-file-ignores 'a.py:E501,b.py:F401'
  3. Prefer the pyproject.toml [tool.ruff.lint.per-file-ignores] table for anything non-trivial

Example fix

# before
ruff check --per-file-ignores E501 .
# after
ruff check --per-file-ignores 'src/legacy/*.py:E501' .
Defensive patterns

Strategy: validation

Validate before calling

# bash: require exactly one colon before passing the flag
pair='src/legacy/*.py:E501'
if [[ "$(tr -cd ':' <<<"$pair" | wc -c)" -ne 1 ]]; then
  echo "need <FilePattern>:<RuleCode>, e.g. 'src/*.py:E501'" >&2; exit 1
fi
ruff check --per-file-ignores "$pair" .

Prevention

When it happens

Trigger: Passing a rule code without a file pattern (`--per-file-ignores E501`), passing only a pattern (`--per-file-ignores 'src/*'`), or using extra colons (`--per-file-ignores 'a.py:E5:01'`, or an unescaped Windows drive path like `C:\x.py:E501` which yields three tokens).

Common situations: Copy-pasting a pyproject.toml per-file-ignores value (which is a table, not a string) onto the CLI; assuming --per-file-ignores takes only a rule code; quoting mistakes in shell scripts.

Related errors


AI-assisted analysis of astral-sh/ruff@d1087a4b9e (2026-08-20). Data as JSON: /api/errors/547c4b551fb0161f. Report an issue: GitHub.