jdx/mise · error
files: cannot unapply these entries:\n{}
Error message
files: cannot unapply these entries:\n{} What it means
Thrown by `mise bootstrap dotfiles unapply` during the first, render-free planning pass over `[dotfiles]` entries. Every entry is planned before anything is deleted; each entry that cannot be verified as mise-owned (drifted content, missing source, foreign symlink, wrong file type) is collected into one aggregate error with a `[dotfiles]."<target>": <reason>` line per failure. The command is all-or-nothing: when this fires, nothing has been removed.
Source
Thrown at src/system/files.rs:1384
/// Remove configured whole-file entries without recursively deleting
/// directories that may contain unmanaged files. Symlinks carry their own
/// ownership evidence. Copies and templates must still match their source
/// unless `--force` was given.
pub(crate) fn plan_unapply<'a>(
requests: &'a [FileRequest],
opts: &UnapplyOpts,
) -> Result<Vec<UnapplyPlan<'a>>> {
let mut todo = vec![];
let mut problems = vec![];
for req in requests {
match plan_unapply_one(req, opts) {
Ok(Some(plan)) => todo.push(plan),
Ok(None) => {}
Err(err) => problems.push(format!(" [dotfiles].\"{}\": {err}", req.target_raw)),
}
}
if !problems.is_empty() {
bail!(
"files: cannot unapply these entries:\n{}",
problems.join("\n")
);
}
Ok(todo)
}
/// Resolve checks that may execute user-authored template functions. This runs
/// only after interactive confirmation, but still before any mutation.
pub(crate) fn resolve_unapply(
config: &Config,
plans: &mut Vec<UnapplyPlan<'_>>,
opts: &UnapplyOpts,
) -> Result<()> {
if opts.dry_run {
return Ok(());
}
let mut problems = vec![];View on GitHub (pinned to 6f52dcdf99)
Solutions
- Read each ` [dotfiles]."<target>": <reason>` line and fix that specific entry: restore the missing source or run `mise bootstrap dotfiles apply` so targets match again
- Re-check after each fix with `mise bootstrap dotfiles unapply --dry-run` (inert, shows the remaining failures)
- If the drifted targets are disposable, re-run with `--force` to skip ownership verification
- Delete `[dotfiles]` entries you no longer manage so unapply stops planning them
Example fix
# before: source was deleted from the dotfiles repo $ rm ~/dotfiles/zshrc $ mise bootstrap dotfiles unapply Error: files: cannot unapply these entries: [dotfiles]."~/.zshrc": source is missing; use --force to remove the target # after: restore the source, verify with dry-run, then unapply $ git -C ~/dotfiles checkout -- zshrc $ mise bootstrap dotfiles unapply --dry-run $ mise bootstrap dotfiles unapply
Defensive patterns
Strategy: validation
Validate before calling
#!/usr/bin/env bash # Gate the real unapply on an inert dry-run so failures surface before # anything is at risk (run in CI or before manual runs). set -euo pipefail if ! mise bootstrap dotfiles unapply --dry-run; then echo "unapply plan failed; fix the entries above or pass --force deliberately" >&2 exit 1 fi mise bootstrap dotfiles unapply --yes
Type guard
// Rust (embedding mise internals): detect this aggregate bail.
fn is_unapply_plan_refused(err: &miette::Report) -> bool {
err.to_string()
.starts_with("files: cannot unapply these entries")
} Try / catch
// Rust: treat planning failure as a hard stop; nothing was mutated,
// so report and re-run after fixing entries (never ignore).
match files::plan_unapply(&reqs, &opts) {
Ok(plans) => { /* proceed to resolve/execute */ }
Err(err) if is_unapply_plan_refused(&err) => {
eprintln!("{err:?}");
std::process::exit(1);
}
Err(err) => return Err(err),
} Prevention
- Keep the dotfiles source repo under version control so any deleted/renamed source is one `git checkout` away
- Never hand-edit a mise-managed target; edit the source and re-apply
- After changing modes or paths in `[dotfiles]`, run `mise bootstrap dotfiles apply` before ever unapplying
- Script unapply as `--dry-run` first, real run second
When it happens
Trigger: Running `mise bootstrap dotfiles unapply` (optionally with target filters) when at least one entry fails `plan_unapply_one`: a copy/template target whose bytes differ from its source, a symlink pointing somewhere other than the configured source, a source file deleted from the dotfiles repo, or a non-directory target for a directory-backed mode.
Common situations: Hand-editing a managed file after apply; renaming/moving the dotfiles source without re-applying; switching an entry's mode (copy->symlink) so the on-disk target no longer matches; another dotfile manager (stow, home-manager) having replaced targets.
Related errors
- no dotfiles matched target filter: {}
- target symlink points to {}, use --force to remove it
- target is not the managed symlink, use --force to remove it
- target is not the managed directory, use --force to remove i
- source directory is missing, so managed children cannot be i
AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22).
Data as JSON: /api/errors/3dfd488b7dba640f.
Report an issue: GitHub.