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
- Set the referenced environment variable in the environment running Ruff (export it in CI/shell profile).
- Replace the variable in `cache-dir` with a literal path, e.g. cache-dir = ".ruff_cache".
- Escape a literal dollar sign as `$$` if you actually want a $ in the path.
- 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
- Export all variables referenced by cache-dir in CI and shell profiles.
- Prefer literal relative paths over variable expansion in cache-dir.
- Escape literal dollar signs as $$ in the config value.
- Validate config on a fresh machine/CI runner before relying on it.
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
- Expected
- No files found under the given path
- The argument `--config=
- Unknown option
- Unrecognized language
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)