{"record":{"id":"622cedfd8d8d0c60","repo":"jdx/mise","slug":"failed-to-add","errorCode":null,"errorMessage":"failed to add {}","messagePattern":"failed to add (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/dotfiles/edit.rs","lineNumber":102,"sourceCode":"            targets: vec![self.target.clone()],\n            changed: false,\n            mode: self.mode.clone(),\n            source: self.source.clone(),\n            global: true,\n            local: false,\n            path: None,\n            dry_run: false,\n            no_apply: true,\n            force: false,\n            yes: true,\n            prompt_secrets: self.prompt_secrets,\n        }\n        .run()\n        .await?;\n\n        config = Config::reset().await?;\n        let Some(path) = source_for_target(&config, &target, &self.target)? else {\n            bail!(\"failed to add {}\", self.target);\n        };\n        open_or_create(&path)?;\n        crate::cli::editor::open_in_editor(&path)?;\n        if self.apply {\n            apply_target(&self.target, self.prompt_secrets).await?;\n        }\n        Ok(())\n    }\n}\n\nfn source_for_target(\n    config: &Config,\n    target: &std::path::Path,\n    raw: &str,\n) -> Result<Option<PathBuf>> {\n    for req in system::files::files_from_config(config)? {\n        if system::files::matches_target(&req.target, &req.target_raw, &[raw.to_string()]) {\n            return Ok(Some(req.source));","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/cli/dotfiles/edit.rs#L84-L120","documentation":"After `dotfiles edit` runs the DotfilesAdd flow to bring a target under management, it re-reads config and calls source_for_target to find the file's backing source path. If the add silently failed to produce a matching entry, edit bails with 'failed to add <target>'.","triggerScenarios":"The DotfilesAdd::run() completes without error but source_for_target on the refreshed Config still returns None — e.g. the add was a no-op because the file is outside the dotfiles root, already symlinked elsewhere, or matched no valid edit entry.","commonSituations":"Target path is a symlink whose source cannot be determined; dotfiles config directory not initialized; filesystem permission problems preventing the add; race where config reset picks up stale state.","solutions":["Check the file exists at the real (non-symlink) path and is readable","Inspect [dotfiles] entries in ~/.config/mise/mise.toml after the failure to see if anything was written","Run `mise dotfiles add <target>` explicitly and observe its output/errors","Re-run `mise dotfiles edit <target>` after a successful add"],"exampleFix":"// before: edit with implicit add failing\nmise dotfiles edit ~/dotfiles/ghostty/config\n// after: add explicitly first, then edit\nmise dotfiles add ~/dotfiles/ghostty/config\nmise dotfiles edit ~/dotfiles/ghostty/config","handlingStrategy":"try-catch","validationCode":"mise dotfiles add \"$target\" && mise config ls | grep -F \"$target\"","typeGuard":null,"tryCatchPattern":"if let Err(e) = edit_target(t) { if e.to_string().starts_with(\"failed to add\") { eprintln!(\"run `mise dotfiles add {t}` explicitly\"); } }","preventionTips":["Run `mise dotfiles add` explicitly instead of relying on edit's implicit add","Confirm the target is a regular readable file, not a dangling symlink","Keep the dotfiles config directory initialized"],"tags":["dotfiles","cli","config"],"backgroundTag":"resource-not-found","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}