jdx/mise · error
managed directory paths
Error message
managed directory paths '{previous}' and '{path}' normalize to the same target '{}' What it means
Thrown while merging managed directory declarations within a config layer when two distinct directory path strings normalize to the same absolute target, mirroring the file-path equivalent. Since two declarations for one directory would be ambiguous, the merge fails and reports both original paths and the normalized target.
Solutions
- Deduplicate by normalized absolute target before writing the config.
- Use one canonical path spelling per directory in each layer.
- Inspect the reported normalized target to find which two strings collide, then remove one declaration.
- If both entries were meant to be different directories, fix the path-building code so targets actually differ.
Example fix
# before [bootstrap.directories] "logs" = true "./logs" = true # after [bootstrap.directories] "/abs/path/to/logs" = true
Defensive patterns
Strategy: validation
Validate before calling
import os
seen = {}
for d in bootstrap.directories:
t = os.path.realpath(os.path.abspath(d))
if t in seen: raise SystemExit(f'{seen[t]} and {d} normalize to {t}')
seen[t] = d Type guard
function uniqueDirTargets(dirs) {
const s = new Set(dirs.map(d => path.resolve(d))); return s.size === dirs.length;
} Prevention
- Normalize directory paths (resolve) before writing them into config.
- Deduplicate generated directory lists by canonical path.
- Pick one path spelling convention (absolute) for directories.
When it happens
Trigger: Within one layer's `bootstrap.directories`, declaring e.g. `logs` and `./logs` (or a relative and equivalent absolute path) so `absolute_target` maps both to one target; generated directory lists containing duplicates under different spellings.
Common situations: Programmatically building the directories map from templates that emit mixed relative/absolute forms; hand-editing where a trailing `./` or redundant component sneaks in; concatenating directory lists from multiple sources into one layer.
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
- conflicting managed directory declarations for
- managed file paths ' ' and ' ' normalize to the same target
- bootstrap service ' ' cannot be both masked and running
- bootstrap service ' ' cannot be both masked and enabled
- conflicting bootstrap secret declarations for
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/323b7ddc813a5309.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/managed_files.rs:488
/// Merges managed directories within one config hierarchy using normal precedence.
fn directories_from_config_files(
config_files: &ConfigMap,
) -> Result<IndexMap<PathBuf, (ManagedDirectoryTomlConfig, ResourceOrigin)>> {
let mut merged = IndexMap::new();
for cf in config_files.values() {
if let Some(bootstrap) = cf.bootstrap_config() {
let origin = ResourceOrigin {
config: cf.get_path().to_path_buf(),
config_root: cf.config_root(),
environment: crate::config::environments_for_config_path(cf.get_path()),
source: None,
};
let mut layer_paths = IndexMap::new();
for (path, directory) in bootstrap.directories {
let target = absolute_target(&path)?;
if let Some(previous) = layer_paths.insert(target.clone(), path.clone()) {
bail!(
"managed directory paths '{previous}' and '{path}' normalize to the same target '{}'",
target.display()
);
}
merged
.entry(target)
.or_insert_with(|| (directory, origin.clone()));
}
}
}
Ok(merged)
}
fn validate_requests(
files: &[ManagedFileRequest],
directories: &[ManagedDirectoryRequest],
) -> Result<()> {
let directory_states = directoriesView on GitHub (pinned to 533346cc37)