astral-sh/ruff · error

Invalid `cache-dir` value

Error message

Invalid `cache-dir` value: {e}

What it means

Ruff expands environment/user variables (via shellexpand) in the configured `cache-dir` setting. If the value contains an undefined variable or malformed syntax (e.g. `$UNSET_VAR` or a bad `${...}` form), expansion fails and configuration loading aborts with this error.

Solutions

  1. Set the referenced environment variable in the environment running Ruff (export it in CI/shell profile).
  2. Replace the variable in `cache-dir` with a literal path, e.g. cache-dir = ".ruff_cache".
  3. Escape a literal dollar sign as `$$` if you actually want a $ in the path.
  4. Validate the config with `ruff check --no-cache` or `ruff config` to isolate the bad value.

Example fix

# before (pyproject.toml)
[tool.ruff]
cache-dir = "$XDG_CACHE_HOME/ruff"  # XDG_CACHE_HOME unset
# after
[tool.ruff]
cache-dir = ".ruff_cache"
Defensive patterns

Strategy: validation

Validate before calling

import os, re
val = "$(grep -oP 'cache-dir\\s*=\\s*"\K[^"]+' pyproject.toml)"
for var in re.findall(r'\$(\w+)|\$\{(\w+)\}', val):
    name = var[0] or var[1]
    assert name in os.environ, f"environment variable {name} referenced in cache-dir is not set"

Try / catch

// CI step: fail fast before running ruff
- run: |
    if grep -q 'cache-dir.*\$' pyproject.toml; then
      grep -oP 'cache-dir\s*=\s*"\K[^$]+(?=\$)' pyproject.toml | while read v; do
        [ -n "${!v+x}" ] || { echo "Missing env var $v for cache-dir"; exit 1; }
      done
    fi
- run: ruff check .

Prevention

When it happens

Trigger: pyproject.toml/ruff.toml sets `cache-dir` referencing an environment variable that is not set, or containing invalid expansion syntax that shellexpand::full rejects.

Common situations: CI environments where the variable is defined locally but not exported, typos in variable names, copying configs between machines, or values like `~/$PROJECT/.ruff_cache` where $PROJECT is unset.

Related errors


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

Appendix: source

Thrown at crates/ruff_workspace/src/configuration.rs:554

            lint.common = lint.common.combine(options.lint_top_level.0);
            lint
        } else {
            LintOptions {
                common: options.lint_top_level.0,
                ..LintOptions::default()
            }
        };

        Ok(Self {
            builtins: options.builtins,
            cache_dir: options
                .cache_dir
                .map(|dir| {
                    let dir = shellexpand::full(&dir);
                    dir.map(|dir| fs::normalize_path_to(dir.as_ref(), project_root))
                })
                .transpose()
                .map_err(|e| anyhow!("Invalid `cache-dir` value: {e}"))?,

            exclude: options.exclude.map(|paths| {
                paths
                    .into_iter()
                    .map(|pattern| {
                        let absolute = GlobPath::normalize(&pattern, project_root);
                        FilePattern::User(pattern, absolute)
                    })
                    .collect()
            }),
            extend: options
                .extend
                .map(|extend| {
                    let extend = shellexpand::full(&extend);
                    extend.map(|extend| PathBuf::from(extend.as_ref()))
                })
                .transpose()
                .map_err(|e| anyhow!("Invalid `extend` value: {e}"))?,

View on GitHub (pinned to 26f38c119c)