{"record":{"id":"cbc337413d8a3c1e","repo":"jdx/mise","slug":"conflicting-managed-directory-declarations-for","errorCode":null,"errorMessage":"conflicting managed directory declarations for {}\n\n  first:\n    {}\n\n  second:\n    {}","messagePattern":"conflicting managed directory declarations for (.+?)\n\n  first:\n    (.+?)\n\n  second:\n    (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/managed_files.rs","lineNumber":430,"sourceCode":"                merged\n                    .entry(target)\n                    .or_insert_with(|| (file, base.clone(), file_origin));\n            }\n        }\n    }\n    Ok(merged)\n}\n\nfn directories_from_config(config: &Config) -> Result<Vec<ManagedDirectoryRequest>> {\n    let mut composed: IndexMap<PathBuf, (ManagedDirectoryTomlConfig, ResourceOrigin)> =\n        IndexMap::new();\n    for config_files in config.bootstrap_config_maps() {\n        for (path, declaration) in directories_from_config_files(config_files)? {\n            if let Some(existing) = composed.get(&path) {\n                if existing.0 == declaration.0 {\n                    continue;\n                }\n                bail!(\n                    \"conflicting managed directory declarations for {}\\n\\n  first:\\n    {}\\n\\n  second:\\n    {}\",\n                    path.display(),\n                    existing.1.conflict_description(),\n                    declaration.1.conflict_description(),\n                );\n            }\n            composed.insert(path, declaration);\n        }\n    }\n    composed\n        .into_iter()\n        .map(|(path, (config, origin))| ManagedDirectoryRequest::from_toml(path, config, origin))\n        .collect()\n}\n\n/// Merges managed directories within one config hierarchy using normal precedence.\nfn directories_from_config_files(\n    config_files: &ConfigMap,","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/managed_files.rs#L412-L448","documentation":"Thrown by directories_from_config when two configuration layers declare the same managed directory path with differing declarations (e.g. different state: present vs absent, or different mode). Because directory declarations must be consistent across layers, the mismatch is reported with both conflict descriptions.","triggerScenarios":"Calling status_requests_from_config or prepare_requests_from_config when bootstrap_config_maps() includes multiple layers that each declare bootstrap.directories for path P with non-equal declarations.","commonSituations":"One config layer marks a directory as absent (cleanup) while another marks it present; different permissions/mode per layer; stale project-level overrides after a team changed the shared config.","solutions":["Read the 'first:'/'second:' conflict descriptions to find the differing field (state or mode).","Remove the directory declaration for that path from one config layer.","Align both layers to the same state and mode if both must exist.","If a directory is intentionally removed in an environment override, ensure no other active layer still declares it present."],"exampleFix":"# before\n# user config: state = \"absent\"  project config: state = \"present\" for /var/log/myapp\n# after\n# remove the user-config declaration, or set both to state = \"present\"","handlingStrategy":"validation","validationCode":"const merged = {};\nfor (const layer of layers) {\n  for (const [path, decl] of Object.entries(layer.directories)) {\n    if (merged[path] && (merged[path].state !== decl.state || merged[path].mode !== decl.mode)) {\n      throw new Error(`conflicting managed directory declarations for ${path}`);\n    }\n    merged[path] = decl;\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep directory state (present/absent) and mode identical across all layers that declare a path.","When removing a directory, purge its declaration from every other active config layer.","Validate merged config before apply to catch state mismatches early."],"tags":["config-conflict","managed-directories","layering"],"backgroundTag":"conflicting-config-options","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}