{"record":{"id":"b9d8a152aba2ad8e","repo":"jdx/mise","slug":"conflicting-managed-file-declarations-for-fi","errorCode":null,"errorMessage":"conflicting managed file declarations for {}\n\n  first:\n    {}\n\n  second:\n    {}","messagePattern":"conflicting managed file 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":354,"sourceCode":"        .into_iter()\n        .map(|(path, (file, base, origin))| {\n            ManagedFileRequest::from_toml(config, path, file, &base, origin, secrets)\n        })\n        .collect()\n}\n\nfn merged_files_from_config(\n    config: &Config,\n) -> Result<IndexMap<PathBuf, (ManagedFileTomlConfig, PathBuf, ResourceOrigin)>> {\n    let mut composed: IndexMap<PathBuf, (ManagedFileTomlConfig, PathBuf, ResourceOrigin)> =\n        IndexMap::new();\n    for config_files in config.bootstrap_config_maps() {\n        for (path, declaration) in merged_files_from_config_files(config_files)? {\n            if let Some(existing) = composed.get(&path) {\n                if managed_file_declarations_match(existing, &declaration) {\n                    continue;\n                }\n                bail!(\n                    \"conflicting managed file declarations for {}\\n\\n  first:\\n    {}\\n\\n  second:\\n    {}\",\n                    path.display(),\n                    existing.2.conflict_description(),\n                    declaration.2.conflict_description(),\n                );\n            }\n            composed.insert(path, declaration);\n        }\n    }\n    Ok(composed)\n}\n\n/// Returns whether sibling declarations produce the same managed file.\nfn managed_file_declarations_match(\n    first: &(ManagedFileTomlConfig, PathBuf, ResourceOrigin),\n    second: &(ManagedFileTomlConfig, PathBuf, ResourceOrigin),\n) -> bool {\n    first.0 == second.0","sourceCodeStart":336,"sourceCodeEnd":372,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/managed_files.rs#L336-L372","documentation":"Thrown by merged_files_from_config when two configuration layers declare the same managed file path but with declarations that do not match (different content, mode, source, etc.). Instead of silently letting a later layer win, the tool reports both declarations verbatim via conflict_description so the user can resolve the conflict.","triggerScenarios":"Calling files_from_config or status_requests_from_config when bootstrap_config_maps() yields multiple config layers that each define managed file for path P with differing declaration fields.","commonSituations":"A project config and a user-global config both manage /etc/myapp/config.toml with different modes or content sources; environment-specific overrides changing only some fields of a managed file declaration.","solutions":["Compare the 'first:' and 'second:' declarations printed in the error to identify the differing field.","Remove the managed-file declaration for that path from one config layer.","Make the declarations identical in both layers if both must remain.","If intentional override is desired, check whether the tool supports explicit layer precedence for managed files; otherwise consolidate the declaration into a single config layer."],"exampleFix":"# before (project config)\n[[bootstrap.files]]\npath = \"/etc/app.conf\"\nmode = 420\n# user config also declares path = \"/etc/app.conf\" with mode = 438\n# after\n# keep the declaration only in project config, or set identical mode in both","handlingStrategy":"validation","validationCode":"// before applying, diff declarations across config layers\nconst merged = {};\nfor (const layer of layers) {\n  for (const [path, decl] of Object.entries(layer.files)) {\n    if (merged[path] && JSON.stringify(merged[path]) !== JSON.stringify(decl)) {\n      throw new Error(`conflicting managed file declarations for ${path}`);\n    }\n    merged[path] = decl;\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Declare each managed file in exactly one config layer.","Keep managed-file declarations in a shared file included by all environments to prevent drift.","Review `first:/second:` output carefully — the differing field is shown verbatim."],"tags":["config-conflict","managed-files","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"}