{"record":{"id":"e69fcb05ceabe140","repo":"jdx/mise","slug":"target-raw-target-must-be-absolute-or-start-wit","errorCode":null,"errorMessage":"{target_raw}: target must be absolute or start with ~/","messagePattern":"(.+?): target must be absolute or start with ~/","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/dotfiles/add.rs","lineNumber":159,"sourceCode":"            }\n        }\n        let config_path = resolve_target_config_path(ConfigPathOptions {\n            global: self.global || !self.local,\n            path: self.path.clone(),\n            env: None,\n            cwd: None,\n            prefer_toml: true,\n            prevent_home_local: true,\n        })?;\n\n        let mut planned = vec![];\n        let managed_edits = system::edits::edits_from_config(&config)?;\n        for target_raw in &self.targets {\n            let target = system::files::resolve_target_arg(target_raw)\n                .components()\n                .collect::<PathBuf>();\n            if target.is_relative() {\n                bail!(\"{target_raw}: target must be absolute or start with ~/\");\n            }\n            if managed\n                .iter()\n                .any(|req| req.mode == FileMode::Track && req.target == target)\n            {\n                bail!(\n                    \"{target_raw}: tracked in place; pass `--mode copy` after `mise bootstrap dotfiles untrack {target_raw}` to seed a source instead\"\n                );\n            }\n            if managed_edits.iter().any(|req| {\n                system::files::matches_target(\n                    &req.path,\n                    &req.path_raw,\n                    std::slice::from_ref(target_raw),\n                )\n            }) {\n                bail!(\n                    \"{target_raw}: target is already managed by [dotfiles] edits; remove or rename those entries before adding a whole-file dotfile\"","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/cli/dotfiles/add.rs#L141-L177","documentation":"Dotfile targets must resolve to a managed location outside the working directory. Each raw target string is passed through resolve_target_arg and normalized; if the resulting path is still relative (neither an absolute path nor starting with `~/`), run_inner bails. This prevents adding dotfiles with cwd-dependent paths, which would make management location-sensitive.","triggerScenarios":"Running `mise bootstrap dotfiles add <relative/path>` where the path is relative and does not expand to an absolute path or `~/...`. E.g. `dotfiles add .zshrc` from home.","commonSituations":"Typing shell-style shorthand paths assuming cwd-relative resolution works; script variables that hold relative paths; copy-pasting paths without the leading `~` or `/`.","solutions":["Use an absolute path (e.g. /home/user/.zshrc) for the target.","Use `~/`-prefixed paths, which resolve_target_arg expands against HOME.","Compute the absolute path in your script: `mise bootstrap dotfiles add \"$HOME/.zshrc\"`."],"exampleFix":"// before\nmise bootstrap dotfiles add .zshrc\n// after\nmise bootstrap dotfiles add ~/.zshrc","handlingStrategy":"validation","validationCode":"function isValidTarget(raw) {\n  return raw.startsWith('~/') || raw.startsWith('/');\n}\nif (!isValidTarget(target)) throw new Error(`use absolute or ~/${''} path: ${target}`);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write dotfile targets as `~/...` or absolute paths.","In scripts, prefix with \"$HOME\" or expand `~` before invoking the CLI.","Never rely on cwd-relative resolution for dotfile targets."],"tags":["cli","dotfiles","path-validation","argument-error"],"backgroundTag":"invalid-argument-format","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}