jdx/mise · error

cannot be recreated as a directory: something else is there…

Error message

{} cannot be recreated as a directory: something else is there now; nothing more was changed

What it means

During restore, mise must recreate deleted directories. If a path that should become a directory currently exists as something else (a file or a symlink), mise refuses to clobber it and aborts the remaining restore. Already-applied steps remain recorded for undo.

Solutions

  1. Inspect the path: if the file/symlink there is disposable, remove it and re-run the restore.
  2. If it holds real data, move it elsewhere first, then re-run the rollback.
  3. Restore a narrower scope that avoids the conflicting path.

Example fix

# before
ls -la src/generated   # -> a regular file blocks the directory restore
rm src/generated       # or: mv src/generated src/generated.bak
# after
mise history undo      # restore now succeeds
Defensive patterns

Strategy: validation

Validate before calling

for d in $restore_dirs; do if [ -e "$d" ] && [ ! -d "$d" ]; then echo "conflict: $d"; fi; done

Prevention

When it happens

Trigger: In the restore_dirs pass of apply_steps, a path in exec.restore_dirs exists (or is a symlink) but is not a real directory, so mkdir would fail or overwrite a non-directory entry.

Common situations: A file was created where a directory used to live after the checkpoint (e.g. a symlink replaced by a regular file, or a build tool wrote a file at the old directory path); leftover state from a prior partial restore.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/95c0f19dc46d17a1. Report an issue: GitHub.

Appendix: source

Thrown at src/system/history/replay.rs:690

                }
            }
        });
        let pending =
            journal::begin_changes("history", &display_path(&step.path), [step.path.clone()])?;
        match &step.action {
            Action::Write { mode, oid } => write_object(repo, step, mode, oid)?,
            Action::Delete => remove(&step.path)?,
            _ => unreachable!("filtered to mutating steps"),
        }
        journal::commit_changes(pending);
        touched.push(step.path.clone());
    }
    for dir in &exec.restore_dirs {
        if dir.is_dir() && !dir.is_symlink() {
            continue;
        }
        if dir.exists() || dir.is_symlink() {
            bail!(
                "{} cannot be recreated as a directory: something else is there now; nothing more was changed",
                display_path(dir)
            );
        }
        if let Some(parent) = dir.parent() {
            file::create_dir_all(parent)?;
        }
        let bits = exec.restore_modes.get(&display_path(dir));
        let builder = std::fs::DirBuilder::new();
        #[cfg(unix)]
        let builder = {
            let mut builder = builder;
            if let Some(bits) = bits {
                use std::os::unix::fs::DirBuilderExt;
                builder.mode(*bits);
            }
            builder
        };

View on GitHub (pinned to 533346cc37)