{"record":{"id":"323b7ddc813a5309","repo":"jdx/mise","slug":"managed-directory-paths-previous-and-path","errorCode":null,"errorMessage":"managed directory paths '{previous}' and '{path}' normalize to the same target '{}'","messagePattern":"managed directory paths '(.+?)' and '(.+?)' normalize to the same target '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/managed_files.rs","lineNumber":488,"sourceCode":"\n/// Merges managed directories within one config hierarchy using normal precedence.\nfn directories_from_config_files(\n    config_files: &ConfigMap,\n) -> Result<IndexMap<PathBuf, (ManagedDirectoryTomlConfig, ResourceOrigin)>> {\n    let mut merged = IndexMap::new();\n    for cf in config_files.values() {\n        if let Some(bootstrap) = cf.bootstrap_config() {\n            let origin = ResourceOrigin {\n                config: cf.get_path().to_path_buf(),\n                config_root: cf.config_root(),\n                environment: crate::config::environments_for_config_path(cf.get_path()),\n                source: None,\n            };\n            let mut layer_paths = IndexMap::new();\n            for (path, directory) in bootstrap.directories {\n                let target = absolute_target(&path)?;\n                if let Some(previous) = layer_paths.insert(target.clone(), path.clone()) {\n                    bail!(\n                        \"managed directory paths '{previous}' and '{path}' normalize to the same target '{}'\",\n                        target.display()\n                    );\n                }\n                merged\n                    .entry(target)\n                    .or_insert_with(|| (directory, origin.clone()));\n            }\n        }\n    }\n    Ok(merged)\n}\n\nfn validate_requests(\n    files: &[ManagedFileRequest],\n    directories: &[ManagedDirectoryRequest],\n) -> Result<()> {\n    let directory_states = directories","sourceCodeStart":470,"sourceCodeEnd":506,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/managed_files.rs#L470-L506","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\n[bootstrap.directories]\n\"logs\" = true\n\"./logs\" = true\n\n# after\n[bootstrap.directories]\n\"/abs/path/to/logs\" = true","handlingStrategy":"validation","validationCode":"import os\nseen = {}\nfor d in bootstrap.directories:\n  t = os.path.realpath(os.path.abspath(d))\n  if t in seen: raise SystemExit(f'{seen[t]} and {d} normalize to {t}')\n  seen[t] = d","typeGuard":"function uniqueDirTargets(dirs) {\n  const s = new Set(dirs.map(d => path.resolve(d))); return s.size === dirs.length;\n}","tryCatchPattern":null,"preventionTips":["Normalize directory paths (resolve) before writing them into config.","Deduplicate generated directory lists by canonical path.","Pick one path spelling convention (absolute) for directories."],"tags":["config","managed-directories","path-normalization","conflict"],"backgroundTag":"conflicting-config-options","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}