jdx/mise · warning · eyre::Report

path "{path_raw}" must be absolute or start with ~/, ignorin

Error message

path "{path_raw}" must be absolute or start with ~/, ignoring entry

What it means

In [dotfiles], edit-entry keys are "<path>/<id>" where the path (after ~ expansion) must be absolute. A relative path is rejected with this warning and the entry is skipped — edits target machine-specific files, so there is no meaningful base for a relative target. Whole-file [dotfiles] entries have their own resolution; this guard applies to block/line edits.

Source

Thrown at src/system/edits.rs:222

fn split_edit_key(path_and_id: &str) -> Option<(String, String)> {
    let (path, id) = path_and_id.rsplit_once('/')?;
    if path.is_empty() || path == "~" || path == "/" || id.is_empty() {
        return None;
    }
    Some((path.to_string(), id.to_string()))
}

fn resolve_entry(
    path_raw: &str,
    id: String,
    entry: EditTomlEntry,
    base: &Path,
    config_path: &Path,
) -> Result<EditRequest> {
    let path = file::replace_path(path_raw);
    if path.is_relative() {
        bail!("path \"{path_raw}\" must be absolute or start with ~/, ignoring entry");
    }
    // ids end up inside marker lines — keep them to characters that can't
    // collide with the marker syntax itself
    if id.is_empty() || !id.chars().all(|c| c.is_alphanumeric() || "_-.".contains(c)) {
        bail!(
            "\"{path_raw}\".{id:?}: ids may only contain letters, digits, '_', '-', and '.', ignoring entry"
        );
    }
    let entry = match entry {
        EditTomlEntry::Block(inline) => EditTomlTable {
            block: Some(inline),
            source: None,
            template: None,
            line: None,
            comment: None,
        },
        EditTomlEntry::Table(table) => table,
    };

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Prefix the path with ~/ ("~/.zshrc/activate") or use a full absolute path ("/etc/hosts/dev")
  2. Replace $HOME-style variables with ~ — only ~ is expanded
  3. Re-run `mise bootstrap dotfiles status` and confirm the entry now appears

Example fix

# before
[dotfiles]
".config/fish/config.fish/mise" = { line = 'eval (mise activate fish)' }

# after
[dotfiles]
"~/.config/fish/config.fish/mise" = { line = 'eval (mise activate fish)' }
Defensive patterns

Strategy: validation

Validate before calling

# every [dotfiles] edit key's path segment must start with / or ~/
grep -E '^"?[^" ]+' mise.toml | ... # or simpler:
[[ "$key" == ~/* || "$key" == /* ]] || echo "edit path must be absolute or ~/-prefixed: $key" >&2

Type guard

fn is_valid_edit_path(path_raw: &str) -> bool {
    let p = mise_path::replace(path_raw); // ~-expanded
    p.is_absolute()
}

Prevention

When it happens

Trigger: A key like ".config/fish/config.fish/mise" (no leading ~ or /), or "$HOME/.zshrc/activate" — $VAR is not expanded, so the path stays relative.

Common situations: Writing $HOME out of shell habit instead of ~; dropping the ~/ when converting a whole-file dotfiles entry to an edit; assuming paths resolve relative to the mise.toml that declared them (they deliberately do not).

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/6ffd3cbbc9c25082. Report an issue: GitHub.