jdx/mise · error

settings. must resolve to an absolute path

Error message

settings.{name} must resolve to an absolute path

What it means

mise normalizes certain storage directory settings (e.g. cache/data/state dirs) and requires them to be absolute. After applying ~ expansion (file::replace_path), the configured value was still relative, so mise cannot safely use it.

Solutions

  1. Change the setting to an absolute path, e.g. cache_dir = "/home/me/.cache/mise" or "~/.cache/mise"
  2. If it was set via env var, export the absolute path
  3. Remove the setting to fall back to mise's default absolute locations

Example fix

# before
[settings]
cache_dir = "tmp/cache"
# after
[settings]
cache_dir = "~/.cache/mise"
Defensive patterns

Strategy: validation

Validate before calling

# shell: ensure storage dir settings are absolute after ~ expansion
for key in cache_dir data_dir state_dir; do
  v=$(tomlq -r ".settings.$key // empty" mise.toml)
  if [ -n "$v" ]; then
    v=${v/#\~/$HOME}
    case "$v" in /*) ;; *) echo "settings.$key must be absolute: $v";; esac
  fi
done

Type guard

// Rust
fn is_absolute_after_expansion(v: &str) -> bool {
    file::replace_path(Path::new(v)).is_absolute()
}

Try / catch

// Rust
match config_result {
    Ok(cfg) => use(cfg),
    Err(e) if e.to_string().contains("must resolve to an absolute path") => {
        eprintln!("make the named settings path absolute (use ~ expansion if needed)");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: During load_sources_from -> normalize_storage_dirs, a settings value for one of the storage-dir keys resolves (after file::replace_path, which only expands ~) to a relative path — e.g. settings cache_dir = "tmp/cache" in mise.toml or MISE_CACHE_DIR-like env relative value.

Common situations: Setting storage dirs to relative paths in project mise.toml (project-relative paths are not allowed for these settings), or templated values producing relative results; ~-prefixed values are fine, bare relative ones are not.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/6f2226833027b268. Report an issue: GitHub.

Appendix: source

Thrown at src/config/settings.rs:659

        if partial.task.cache.remote_url.is_none() {
            partial.task.cache.remote_url = Some(v);
        }
    }
    partial
}

fn normalize_storage_dirs(settings: &mut Settings) -> Result<()> {
    for (name, path) in [
        ("shims_dir", &mut settings.shims_dir),
        ("system_installs_dir", &mut settings.system_installs_dir),
        ("system_shims_dir", &mut settings.system_shims_dir),
    ] {
        let Some(configured) = path.take() else {
            continue;
        };
        let configured = file::replace_path(&configured);
        if !configured.is_absolute() {
            bail!("settings.{name} must resolve to an absolute path");
        }
        *path = Some(configured);
    }
    Ok(())
}

fn strip_local_only_settings(settings: &mut toml::Table, path: &Path, is_global: bool) {
    if is_global {
        return;
    }

    for key in SETTINGS_META
        .iter()
        .filter_map(|(key, meta)| meta.global_only.then_some(*key))
    {
        if let Some(value) = remove_nested_toml_value(settings, key)
            && should_warn_ignored_global_only_value(&value)
        {

View on GitHub (pinned to 533346cc37)