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

  1. Deduplicate by normalized absolute target before writing the config.
  2. Use one canonical path spelling per directory in each layer.
  3. Inspect the reported normalized target to find which two strings collide, then remove one declaration.
  4. 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

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


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 = directories

View on GitHub (pinned to 533346cc37)