jdx/mise · error · eyre::Report
managed path ' ' cannot be present while managed ancestor '…
Error message
managed path '{}' cannot be present while managed ancestor '{}' is absent What it means
validate_present_ancestors enforces logical consistency of declared states along the path hierarchy: a path declared Present cannot sit under a managed ancestor directory declared Absent, since removing the ancestor removes the child. Called from validate_requests and directly by status_requests_from_config for each present file, it scans path.ancestors() against the directory state map and bails on the first Absent ancestor.
Solutions
- Set the ancestor directory's state to "present" so the child can exist.
- Change the child file's state to "absent" or remove its entry, since the tree is being removed anyway.
- Move the file outside the Absent-managed subtree if it must persist.
Example fix
# before
[bootstrap.directories]
"/opt/legacy" = { state = "absent" }
[bootstrap.files]
"/opt/legacy/keep.conf" = { content = "...", state = "present" }
# after
[bootstrap.files]
"/etc/keep.conf" = { content = "...", state = "present" } Defensive patterns
Strategy: validation
Validate before calling
// fail fast if any present file sits under an absent-managed directory
fn check_absent_ancestors(files: &[PathBuf], absent_dirs: &std::collections::HashSet<PathBuf>) -> Result<(), String> {
for f in files {
for anc in f.ancestors().skip(1) {
if absent_dirs.contains(anc) {
return Err(format!("{} present under absent {}", f.display(), anc.display()));
}
}
}
Ok(())
} Prevention
- When marking a directory absent, remove or flip all entries beneath it in the same change.
- Prefer declaring the directory absent alone and letting recursive removal handle children.
- Add a config lint that walks ancestors for every present file entry.
When it happens
Trigger: status_requests_from_config or validate_requests encountering a [bootstrap.files] entry with state = "present" whose ancestor path exists in [bootstrap.directories] with state = "absent".
Common situations: Deleting a directory tree but forgetting to flip contained file entries to absent or remove them; partially reverting a cleanup commit; templated configs where directory state is variable but file state is hardcoded.
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
- [bootstrap.directories].
- [bootstrap.files]." ": absent files must not declare source…
- [bootstrap.files]." ": present files require source or…
- [bootstrap.files]." ": source and content are mutually…
- managed path ' ' ( ) conflicts with ancestor ' ' ( )…
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/f6c23d4e6329e831.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/managed_files.rs:573
}
}
Ok(())
}
fn validate_present_ancestors(
path: &Path,
state: ManagedState,
directory_states: &std::collections::HashMap<&Path, ManagedState>,
) -> Result<()> {
if state != ManagedState::Present {
return Ok(());
}
if let Some(parent) = path
.ancestors()
.skip(1)
.find(|parent| directory_states.get(parent) == Some(&ManagedState::Absent))
{
bail!(
"managed path '{}' cannot be present while managed ancestor '{}' is absent",
path.display(),
parent.display()
);
}
Ok(())
}
impl ManagedFileRequest {
fn from_toml(
root_config: &Config,
path: PathBuf,
config: ManagedFileTomlConfig,
base: &Path,
origin: ResourceOrigin,
secrets: &super::secrets::SecretValues,
) -> Result<Self> {
let owner = nonempty("owner", config.owner)?;View on GitHub (pinned to 533346cc37)