{"record":{"id":"2f645185e05d44fc","repo":"jdx/mise","slug":"cannot-add-dependency-to-missing-bootstrap-resourc","errorCode":null,"errorMessage":"cannot add dependency to missing bootstrap resource '{resource}'","messagePattern":"cannot add dependency to missing bootstrap resource '(.+?)'","errorType":"validation","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/system/resources.rs","lineNumber":139,"sourceCode":"pub struct BootstrapPlan {\n    resources: IndexMap<ResourceId, ResourcePlan>,\n}\n\nimpl BootstrapPlan {\n    pub fn insert(&mut self, resource: ResourcePlan) -> Result<()> {\n        if self.resources.contains_key(&resource.id) {\n            bail!(\n                \"bootstrap resource '{}' is declared more than once\",\n                resource.id\n            );\n        }\n        self.resources.insert(resource.id.clone(), resource);\n        Ok(())\n    }\n\n    pub fn add_dependency(&mut self, resource: &ResourceId, dependency: ResourceId) -> Result<()> {\n        let Some(resource) = self.resources.get_mut(resource) else {\n            bail!(\"cannot add dependency to missing bootstrap resource '{resource}'\");\n        };\n        if !resource.depends_on.contains(&dependency) {\n            resource.depends_on.push(dependency);\n        }\n        Ok(())\n    }\n\n    pub fn output(&self) -> Result<BootstrapPlanOutput<'_>> {\n        let resources = self.ordered()?;\n        let mut summary = PlanSummary::default();\n        for resource in &resources {\n            summary.add(resource.action);\n        }\n        Ok(BootstrapPlanOutput { resources, summary })\n    }\n\n    fn ordered(&self) -> Result<Vec<&ResourcePlan>> {\n        let mut incoming = self","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/system/resources.rs#L121-L157","documentation":"BootstrapPlan::add_dependency(resource, dep) requires the dependent resource to already exist in the plan (added via insert()); it bails immediately when `resource` is unknown. The dependency target may be inserted later — only the dependent must exist first. In shipped wiring (accounts, files, directories, services, firewall, compose) the dependent is always inserted before edges are added, so this error indicates a dependency was added for an id that was never declared or was filtered out.","triggerScenarios":"Programmatic use: calling plan.add_dependency(&ResourceId::new(\"user\", \"x\"), ...) before plan.insert of that user; a section emitting dependencies for a resource it did not insert (e.g. firewall rules referencing a policy resource that produced no plans).","commonSituations":"Custom bootstrap adapters built on BootstrapPlan; version skew where one section stops emitting a resource that another section still depends on; disabled sections whose edges are added unconditionally.","solutions":["Insert the resource with plan.insert(...) before adding dependencies that point at it","Check the id spelling: the error prints `kind:name` — it must match the inserted ResourceId exactly (kind and name, case-sensitive)","If the resource can be legitimately absent (feature disabled), skip adding its dependency edges too"],"exampleFix":"// before\nplan.add_dependency(&ResourceId::new(\"user\", \"alice\"), ResourceId::new(\"group\", \"devs\"))?;\nplan.insert(alice_plan)?; // too late\n\n// after\nplan.insert(alice_plan)?;\nplan.add_dependency(&ResourceId::new(\"user\", \"alice\"), ResourceId::new(\"group\", \"devs\"))?;","handlingStrategy":"validation","validationCode":"// before adding an edge, confirm the dependent exists\nif plan_contains(&plan, &resource_id) {\n    plan.add_dependency(&resource_id, dependency)?;\n} else {\n    // skip or insert the resource first\n}\n\nfn plan_contains(plan: &BootstrapPlan, id: &ResourceId) -> bool {\n    plan.output() // or expose a contains check; ids print as `kind:name`\n        .map(|o| o.resources.iter().any(|r| &r.id == id))\n        .unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always insert a resource before wiring dependencies from it","When a section can be disabled, guard both its insert and its dependency edges with the same condition","Log the `kind:name` ids you insert so edge targets can be checked by eye"],"tags":["mise","bootstrap","resources","dependencies","plan"],"backgroundTag":"missing-dependency-declaration","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}