jdx/mise · error

managed path ' ' ( ) conflicts with ancestor ' ' ( )…

Error message

managed path '{}' ({}) conflicts with ancestor '{}' ({}): parent directories must be created before children and removed after children; adjust their phase declarations

What it means

Managed paths participate in an ordering contract: an ancestor directory declared with a create/remove phase must have a phase compatible with its descendants (parents created before children, removed after children). validate_requests walks each path's ancestors and bails when the child/parent phase combination (e.g. child PostPackages, parent PrePackages, or other invalid pairings) violates that contract.

Solutions

  1. Change the parent directory's phase so it is created before (and removed after) its child paths.
  2. Alternatively move the child path's phase to match or follow its parent's creation phase.
  3. Split the declaration so conflicting paths are no longer ancestor/descendant.

Example fix

# before
[bootstrap.directories]
"/var/lib/app" = { state = "present", phase = "post-packages" }

[bootstrap.files]
"/var/lib/app/data.db" = { state = "absent", phase = "pre-packages" }

# after
[bootstrap.directories]
"/var/lib/app" = { state = "present", phase = "pre-packages" }

[bootstrap.files]
"/var/lib/app/data.db" = { state = "absent", phase = "post-packages" }
Defensive patterns

Strategy: validation

Validate before calling

// ensure every file's managed ancestor directory has an earlier (or equal) phase
fn check_phases(files: &[(PathBuf, Phase)], dirs: &[(PathBuf, Phase)]) -> Result<(), String> {
    for (fpath, fphase) in files {
        for (dpath, dphase) in dirs {
            if fpath.starts_with(dpath) && phase_rank(dphase) > phase_rank(fphase) {
                return Err(format!("{} ({:?}) precedes {} ({:?})", dpath.display(), dphase, fpath.display(), fphase));
            }
        }
    }
    Ok(())
}

Prevention

When it happens

Trigger: status_requests_from_config or prepare_requests_from_config on a config where a managed path and one of its managed ancestor directories have phases whose combination fails the compatibility check (e.g. child phase PostPackages while parent phase PrePackages in an ordering-sensitive pairing).

Common situations: Declaring a log dir as PrePackages but files inside it as PostPackages; adding a nested file entry without updating the parent directory's phase; refactorings that reorder package installation phases.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

Thrown at src/system/managed_files.rs:547

        )
    {
        for parent in directories
            .iter()
            .filter(|dir| path != &dir.path && path.starts_with(&dir.path))
        {
            let invalid = match (state, parent.state) {
                (ManagedState::Present, ManagedState::Present) => {
                    phase == ManagedFilePhase::PrePackages
                        && parent.phase == ManagedFilePhase::PostPackages
                }
                (ManagedState::Absent, ManagedState::Absent) => {
                    phase == ManagedFilePhase::PostPackages
                        && parent.phase == ManagedFilePhase::PrePackages
                }
                _ => false,
            };
            if invalid {
                bail!(
                    "managed path '{}' ({}) conflicts with ancestor '{}' ({}): parent directories must be created before children and removed after children; adjust their phase declarations",
                    path.display(),
                    phase.as_str(),
                    parent.path.display(),
                    parent.phase.as_str()
                );
            }
        }
    }
    Ok(())
}

fn validate_present_ancestors(
    path: &Path,
    state: ManagedState,
    directory_states: &std::collections::HashMap<&Path, ManagedState>,
) -> Result<()> {
    if state != ManagedState::Present {

View on GitHub (pinned to 533346cc37)