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

untrack resolves each target argument via resolve_target_arg and requires the result to be absolute (possibly via ~/ expansion). Relative targets cannot be mapped onto the tracked set unambiguously, so the command rejects them before doing work.

Source

Thrown at src/cli/dotfiles/untrack.rs:38

    #[usage(value_name = "PATH", required = true)]
    targets: Vec<String>,
}

impl DotfilesUntrack {
    pub(crate) async fn run(self) -> Result<()> {
        let _declarations = super::track::declaration_lock()?;
        let config = Config::get().await?;
        let managed = crate::system::files::files_from_config(&config)?;
        let tracked = TrackedSet::effective().await?;
        let global = crate::config::global_shared_config_path();
        let local = super::track::declaration_file(true)?;
        let mut touched: Vec<PathBuf> = 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 ~/");
            }
            let key = super::track::normalized_target(&target);
            let path = normalize_target(&target);
            match managed
                .iter()
                .find(|req| req.target == target && req.mode == FileMode::Track)
            {
                Some(req) => {
                    let declared_in = &req.origin.config;
                    if crate::config::is_system_config(declared_in)
                        || !crate::config::is_global_config(declared_in)
                    {
                        // inherited: switch it off on this machine
                        let mut doc = super::track::read_document(&local)?;
                        let mut table = toml_edit::InlineTable::new();
                        table.insert(
                            "mode",
                            Value::String(toml_edit::Formatted::new("track".into())),

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Use an absolute path: `mise dotfiles untrack /home/me/.vimrc`
  2. Use `~/` expansion: `mise dotfiles untrack ~/.vimrc`
  3. Quote the argument so the shell does not mangle `~`

Example fix

// before
mise dotfiles untrack .config/starship.toml
// after
mise dotfiles untrack ~/.config/starship.toml
Defensive patterns

Strategy: validation

Validate before calling

# validate target before calling untrack
case "$target" in
  /*|~/*) mise dotfiles untrack "$target" ;;
  *) echo "use absolute or ~/ path" ;;
esac

Try / catch

mise dotfiles untrack "$target" || echo "provide an absolute or ~/-prefixed path"

Prevention

When it happens

Trigger: Running `mise dotfiles untrack <target>` where the target neither is an absolute path nor begins with `~/` — e.g. `mise dotfiles untrack .vimrc` or `untrack src/../dotfiles` after component normalization resolves to a relative path.

Common situations: Typing a bare filename because `track` accepted a relative-ish form interactively; running from the dotfiles directory and assuming relative paths work; shell expansion stripping the leading `~`.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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