{"record":{"id":"c59bdb7c9b28f7dc","repo":"jdx/mise","slug":"managed-file-paths-previous-and-path-norma","errorCode":null,"errorMessage":"managed file paths '{previous}' and '{path}' normalize to the same target '{}'","messagePattern":"managed file paths '(.+?)' and '(.+?)' normalize to the same target '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/managed_files.rs","lineNumber":427,"sourceCode":"    // the nearer project declaration.\n    for cf in config_files.values() {\n        if let Some(bootstrap) = cf.bootstrap_config() {\n            let mut layer_paths = IndexMap::new();\n            let base = cf\n                .get_path()\n                .parent()\n                .unwrap_or_else(|| Path::new(\".\"))\n                .to_path_buf();\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            for (path, file) in bootstrap.files {\n                let target = absolute_target(&path)?;\n                if let Some(previous) = layer_paths.insert(target.clone(), path.clone()) {\n                    bail!(\n                        \"managed file paths '{previous}' and '{path}' normalize to the same target '{}'\",\n                        target.display()\n                    );\n                }\n                let mut file_origin = origin.clone();\n                file_origin.source = file\n                    .source\n                    .as_deref()\n                    .map(|source| resolve_source_path(&base, source));\n                merged\n                    .entry(target)\n                    .or_insert_with(|| (file, base.clone(), file_origin));\n            }\n        }\n    }\n    Ok(merged)\n}\n","sourceCodeStart":409,"sourceCodeEnd":445,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/managed_files.rs#L409-L445","documentation":"Thrown while merging managed file declarations across config layers when two syntactically different paths normalize (via `absolute_target`) to the same absolute target file. Allowing it would make which declaration wins order-dependent, so the library rejects the ambiguity, reporting both original paths and the shared normalized target.","triggerScenarios":"Declaring the same file via a relative path in one layer and an absolute path in another (e.g. `config.conf` vs `/full/path/config.conf`); paths differing only by redundant `./` segments or symlink-resolving components that canonicalize to the same target.","commonSituations":"Configs generated by tooling that emits relative paths while hand-written layers use absolute ones; after changing working-directory assumptions, relative paths now resolve onto absolute ones declared elsewhere; duplicated entries across included config files.","solutions":["Use one canonical (usually absolute) path for the target across all layers.","Compute the normalized target (`absolute_target`) for both reported paths and see why they collide.","Remove the duplicate declaration or give the second file a distinct target path.","Audit generated/template configs for path-building logic that can emit equivalent-but-different strings."],"exampleFix":"# before\n[bootstrap.files.\"app/config.conf\"]      # layer A (relative)\n[bootstrap.files.\"/etc/app/config.conf\"] # layer B (absolute)\n\n# after\n[bootstrap.files.\"/etc/app/config.conf\"] # single canonical path","handlingStrategy":"validation","validationCode":"import os\nseen = {}\nfor p in all_file_paths:\n  t = os.path.realpath(os.path.abspath(p))\n  if t in seen: raise SystemExit(f'{seen[t]} and {p} normalize to {t}')\n  seen[t] = p","typeGuard":"function normalize(p) { return path.resolve(p); }\nfunction uniqueTargets(paths) {\n  const s = new Set(paths.map(normalize)); return s.size === paths.length;\n}","tryCatchPattern":null,"preventionTips":["Standardize on absolute paths for managed files.","Normalize (resolve) paths before adding them to config.","Deduplicate generated path lists by canonical target."],"tags":["config","managed-files","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"}