{"record":{"id":"0dd13155efdd6f64","repo":"jdx/mise","slug":"cannot-verify-use-force-to-remove-it","errorCode":null,"errorMessage":"cannot verify {}; use --force to remove it","messagePattern":"cannot verify (.+?); use --force to remove it","errorType":"exception","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/system/files.rs","lineNumber":1678,"sourceCode":"    Ok(())\n}\n\nfn plan_regular_file(\n    source: &Path,\n    target: &Path,\n    force: bool,\n    paths: &mut IndexMap<PathBuf, ()>,\n) -> Result<()> {\n    if !target.exists() && !target.is_symlink() {\n        return Ok(());\n    }\n    if source.is_file() {\n        plan_expected_content(&file::read(source)?, target, force, paths)\n    } else if force {\n        paths.insert(target.to_path_buf(), ());\n        Ok(())\n    } else {\n        bail!(\n            \"cannot verify {}; use --force to remove it\",\n            target.display_user()\n        )\n    }\n}\n\nfn plan_expected_content(\n    expected: &[u8],\n    target: &Path,\n    force: bool,\n    paths: &mut IndexMap<PathBuf, ()>,\n) -> Result<()> {\n    if force || (target.is_file() && !target.is_symlink() && file::read(target)? == expected) {\n        paths.insert(target.to_path_buf(), ());\n        Ok(())\n    } else {\n        bail!(\n            \"{} differs from its managed source; use --force to remove it\",","sourceCodeStart":1660,"sourceCodeEnd":1696,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/system/files.rs#L1660-L1696","documentation":"While walking directory-backed entries, mise removes a target child only when it can compare it with the matching source item. If the target exists but the source item is not a readable regular file (deleted from the repo, replaced by a directory, or a broken symlink — `is_file()` follows links), ownership cannot be verified and `--force` is required.","triggerScenarios":"`plan_regular_file` invoked with a (source, target) pair from `walk_source_files` (copy / symlink-each directory modes) or `plan_single_file`, where the target exists, `source.is_file()` is false, and force is false.","commonSituations":"Files were removed from the dotfiles source dir after apply but their copied children remain; a source item became a directory; a broken symlink sits in the source tree.","solutions":["Restore the missing source items (`git checkout -- <dir>`), then unapply","Use `--force` to remove the unverifiable targets","Clean stale entries out of the source tree so apply/unapply stay symmetric"],"exampleFix":"# before: a file was dropped from the source dir after apply\n$ git -C ~/dotfiles log --oneline -1 -- nvim/lua.lua   # deleted in a cleanup commit\n$ mise bootstrap dotfiles unapply\nError: cannot verify ~/.config/nvim/lua.lua; use --force to remove it\n\n# after: restore it, then unapply verifies the child\n$ git -C ~/dotfiles checkout HEAD~1 -- nvim/lua.lua\n$ mise bootstrap dotfiles unapply","handlingStrategy":"validation","validationCode":"# Every tracked file under directory sources must exist on disk.\ncd ~/dotfiles && git status --porcelain | grep '^.D' && { echo 'deleted sources present'; exit 1; } || true","typeGuard":"fn is_unverifiable_child(err: &miette::Report) -> bool {\n    err.to_string().starts_with(\"cannot verify\")\n        && err.to_string().contains(\"use --force to remove it\")\n}","tryCatchPattern":null,"preventionTips":["Commit deletions of managed sources together with target cleanup","Avoid broken symlinks inside source directories","Run `git -C ~/dotfiles status` before unapply to catch half-done reorganizations"],"tags":["mise","dotfiles","copy","symlink-each","missing-source","unapply"],"backgroundTag":"missing-source-file","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T20:17:18.057Z"}