jdx/mise · error

{target_raw}: target must be absolute or start with ~/

Error message

{target_raw}: target must be absolute or start with ~/

What it means

`mise bootstrap dotfiles track <target>` requires each target to resolve to an absolute path (or a `~/`-prefixed path). `resolve_target_arg` normalizes the input; if the result is still relative, track refuses because tracked dotfiles must be addressed unambiguously across shells and checkpoint restores.

Source

Thrown at src/cli/dotfiles/track.rs:65

    yes: bool,
}

impl DotfilesTrack {
    pub(crate) async fn run(self) -> Result<()> {
        let _declarations = declaration_lock()?;
        let config = Config::get().await?;
        let managed = crate::system::files::composed_files_from_config(&config)?;
        let global = declaration_file(false)?;
        let mut edits: BTreeMap<PathBuf, DeclarationEdit> = BTreeMap::new();
        let mut locations = BTreeMap::new();
        let mut declared: Vec<(String, PathBuf)> = vec![];
        let mut manual = vec![];
        for target_raw in &self.targets {
            let target = crate::system::files::resolve_target_arg(target_raw)
                .components()
                .collect::<PathBuf>();
            if target.is_relative() {
                bail!("{target_raw}: target must be absolute or start with ~/");
            }
            crate::system::history::tracked::ensure_portable_ancestors(&target)?;
            let target_key = normalized_target(&target);
            if !target.exists() && !target.is_symlink() {
                warn!(
                    "dotfiles: {} does not exist yet; it is captured once it does",
                    target.display_user()
                );
            }
            let existing = managed
                .iter()
                .find(|req| req.target == target && req.mode == FileMode::Track);
            let config_path = if let Some(existing) = existing
                && crate::config::is_global_config(&existing.origin.config)
                && !crate::config::is_system_config(&existing.origin.config)
            {
                existing.origin.config.clone()
            } else if managed

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Prefix the path with `~/` or use an absolute path: `mise bootstrap dotfiles track ~/dotfiles/vimrc`
  2. Expand `$HOME` or `.` in scripts before calling track

Example fix

// before
mise bootstrap dotfiles track dotfiles/vimrc
// after
mise bootstrap dotfiles track ~/dotfiles/vimrc
Defensive patterns

Strategy: validation

Validate before calling

case "$target" in
  /*|~/*) ;; # ok
  *) target="$HOME/${target#./}" ;;
esac

Prevention

When it happens

Trigger: Running `dotfiles track` with a bare relative path like `dotfiles/vimrc` or `./config` that neither starts with `/` nor `~/` and cannot be anchored.

Common situations: Typing a path relative to the current directory out of habit; scripting track calls with relative paths; copy-pasting paths from listings without expansion.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/2a7155e3b493058e. Report an issue: GitHub.