{"record":{"id":"a9b2ae5fac9b1dae","repo":"jdx/mise","slug":"bootstrap-resource-resource-requires-owner-o","errorCode":null,"errorMessage":"bootstrap resource '{resource}' requires owner '{owner}', but that user is absent","messagePattern":"bootstrap resource '(.+?)' requires owner '(.+?)', but that user is absent","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/resources.rs","lineNumber":713,"sourceCode":"\nfn add_account_dependencies(\n    plan: &mut BootstrapPlan,\n    resource: &ResourceId,\n    state: super::managed_files::ManagedState,\n    owner: Option<&str>,\n    group: Option<&str>,\n    user_states: &HashMap<String, super::accounts::AccountState>,\n    group_states: &HashMap<String, super::accounts::AccountState>,\n) -> Result<()> {\n    if state != super::managed_files::ManagedState::Present {\n        return Ok(());\n    }\n    if let Some(owner) = owner {\n        match user_states.get(owner) {\n            Some(super::accounts::AccountState::Present) => {\n                plan.add_dependency(resource, ResourceId::new(\"user\", owner))?;\n            }\n            Some(super::accounts::AccountState::Absent) => bail!(\n                \"bootstrap resource '{resource}' requires owner '{owner}', but that user is absent\"\n            ),\n            None => {}\n        }\n    }\n    if let Some(group) = group {\n        match group_states.get(group) {\n            Some(super::accounts::AccountState::Present) => {\n                plan.add_dependency(resource, ResourceId::new(\"group\", group))?;\n            }\n            Some(super::accounts::AccountState::Absent) => bail!(\n                \"bootstrap resource '{resource}' requires group '{group}', but that group is absent\"\n            ),\n            None => {}\n        }\n    }\n    Ok(())\n}","sourceCodeStart":695,"sourceCodeEnd":731,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/resources.rs#L695-L731","documentation":"A resource declares an owner account, and account planning resolved that user to AccountState::Absent. A resource cannot be owned by a user the plan will remove or never create, so add_account_dependencies (called from plan) bails instead of wiring a dependency to a nonexistent user resource.","triggerScenarios":"Calling plan with any bootstrap resource (directory, file, compose project) whose owner is set to a username for which a user resource exists but is declared Absent.","commonSituations":"Retiring a service account while forgetting resources still owned by it; a config layer marks a user absent while another layer's resources reference it as owner; renaming a user without updating owner fields.","solutions":["Mark the owning user Present (or drop its Absent declaration)","Reassign the resource's owner to an existing Present user","Remove the owner field if default ownership is acceptable"],"exampleFix":"// before\nuser(\"svc-old\", state: \"absent\")\nresource(owner: \"svc-old\")\n// after\nresource(owner: \"svc-new\")","handlingStrategy":"validation","validationCode":"const users = new Map(accountResources.filter(r => r.kind === 'user').map(r => [r.name, r.state]));\nfor (const res of resources) if (res.owner && users.get(res.owner) === 'absent') throw new Error(`${res.id}: owner ${res.owner} is declared absent`);","typeGuard":"function ownerExists(res, users) { return !res.owner || users.get(res.owner) === 'present'; }","tryCatchPattern":"try { plan = planner.plan(); } catch (e) { if (String(e).includes('requires owner') && e.message.includes('is absent')) { reassignOwner(config); } else throw e; }","preventionTips":["Before retiring a user account, grep for it as an owner across all resource definitions","Use a single source of truth for account state so all layers agree","Prefer group-based ownership over individual service accounts where possible"],"tags":["accounts","users","bootstrap"],"backgroundTag":"user-not-found","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"}