{"record":{"id":"46581fade5f75f20","repo":"jdx/mise","slug":"file-cannot-be-present-while-managed-parent","errorCode":null,"errorMessage":"file '{}' cannot be present while managed parent '{}' is absent","messagePattern":"file '(.+?)' cannot be present while managed parent '(.+?)' is absent","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/resources.rs","lineNumber":534,"sourceCode":"            let parent_id = ResourceId::new(\"directory\", parent.to_string_lossy());\n            match (file.state, parent_state) {\n                (\n                    super::managed_files::ManagedState::Present,\n                    super::managed_files::ManagedState::Present,\n                ) => {\n                    plan.add_dependency(&id, parent_id)?;\n                }\n                (\n                    super::managed_files::ManagedState::Absent,\n                    super::managed_files::ManagedState::Absent,\n                ) => {\n                    plan.add_dependency(&parent_id, id)?;\n                }\n                (\n                    super::managed_files::ManagedState::Present,\n                    super::managed_files::ManagedState::Absent,\n                ) => {\n                    bail!(\n                        \"file '{}' cannot be present while managed parent '{}' is absent\",\n                        file.path.display(),\n                        parent.display()\n                    );\n                }\n                (\n                    super::managed_files::ManagedState::Absent,\n                    super::managed_files::ManagedState::Present,\n                ) => {}\n            }\n        }\n    }\n    for resource in unavailable_files {\n        plan.insert(resource)?;\n    }\n    let builtin_packages = super::packages_from_config(config)\n        .into_iter()\n        .filter(|packages| !packages.manager.is_plugin())","sourceCodeStart":516,"sourceCodeEnd":552,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/resources.rs#L516-L552","documentation":"Same invariant as the directory case, applied to a managed file: the file is declared Present while its managed parent directory is declared Absent. The planner bails because the resulting plan would be contradictory (delete the parent but keep the file inside it).","triggerScenarios":"Calling plan with a file resource in ManagedState::Present whose resolved parent directory resource is in ManagedState::Absent.","commonSituations":"A cleanup config removes a directory while an unrelated block still manages a file inside it; someone set the directory to absent expecting its managed file to be relocated; layered config files disagree about the parent.","solutions":["Mark the parent directory Present, or drop its Absent declaration","Mark the file Absent as well if the whole subtree is meant to be removed","Move the managed file to a directory that is actually kept"],"exampleFix":"// before\n{\"dir\": \"/etc/myapp\", \"state\": \"absent\"}\n{\"file\": \"/etc/myapp/app.conf\", \"state\": \"present\"}\n// after\n{\"dir\": \"/etc/myapp\", \"state\": \"present\"}\n{\"file\": \"/etc/myapp/app.conf\", \"state\": \"present\"}","handlingStrategy":"validation","validationCode":"const dirStates = new Map(dirs.map(d => [d.path, d.state]));\nfor (const f of files) {\n  const parent = dirname(f.path);\n  if (f.state === 'present' && dirStates.get(parent) === 'absent') throw new Error(`file ${f.path} present but parent ${parent} absent`);\n}","typeGuard":"function fileParentsValid(files, dirStates) { return files.every(f => f.state !== 'present' || dirStates.get(dirname(f.path)) !== 'absent'); }","tryCatchPattern":"try { plan = planner.plan(); } catch (e) { if (String(e).includes(\"file '\") && e.message.includes('managed parent')) { fixFileParentDeclarations(config); } else throw e; }","preventionTips":["Treat file resources and their parent directory resources as one unit when changing state","Search the config for files under any directory you plan to mark absent","Prefer marking whole subtrees absent together rather than per-resource"],"tags":["filesystem","file","config-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"}