jdx/mise · error

files: cannot unapply these entries: {}

Error message

files: cannot unapply these entries:
{}

What it means

Aggregate error from building an unapply plan: some `[files]` entries could not be planned for removal, and their per-entry errors (prefixed with the entry's target_raw key) are listed under a common header. Nothing from the failing entries is unapplied.

Source

Thrown at src/system/files.rs:2326

/// 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 afd2eddd3a)

Solutions

  1. Fix each listed `[files]."target"` entry per its embedded error (restore the source/repo or correct paths).
  2. Remove obsolete [[files]] entries from mise.toml if they should no longer be managed.
  3. Re-run unapply once all listed entries plan successfully.

Example fix

// before (mise.toml)
[[files]]
source = "~/old-dotfiles/zshrc"  # repo deleted
target = "~/.zshrc"

// after
# remove the stale entry or repoint source:
[[files]]
source = "~/dotfiles/zshrc"
target = "~/.zshrc"
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_unapply_targets_managed(config: &toml::Value) -> anyhow::Result<()> {
    // every [[files]] entry must still have an existing source repo and a target that is a symlink or absent
    for entry in files_entries(config) {
        let target = std::path::Path::new(&expand(&entry.target));
        if target.exists() && !target.is_symlink() && target.is_file() {
            anyhow::bail!("target {} is a regular file; not a managed symlink", entry.target);
        }
    }
    Ok(())
}

Try / catch

match result {
    Err(e) if e.to_string().contains("cannot unapply these entries") => {
        eprintln!("Unapply blocked; fix or drop the listed [files] entries:\n{e}");
    }
    Err(e) => return Err(e),
    Ok(todo) => unapply(todo),
}

Prevention

When it happens

Trigger: Calling files unapply when planning a removal for an entry fails — e.g. the source is gone, the Git repo is missing, or the target cannot be matched back to a managed plan (Ok(None)/Err paths in per-entry planning).

Common situations: User deleted the dotfiles repo but left the config entry; source/target paths changed; entries referencing stale targets from an old configuration.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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