jdx/mise · error · eyre::Report
bootstrap resource '{}' depends on missing resource '{}'
Error message
bootstrap resource '{}' depends on missing resource '{}' What it means
BootstrapPlan::ordered() — invoked via output(), which plan() always calls at the end for validation — walks every resource's depends_on list and bails if an entry refers to a resource id that was never inserted. Unlike the add_dependency guard (which checks only the dependent side at edge-creation time), this validates the dependency side and also catches plans whose ResourcePlans were inserted with depends_on pre-populated.
Source
Thrown at src/system/resources.rs:171
Ok(BootstrapPlanOutput { resources, summary })
}
fn ordered(&self) -> Result<Vec<&ResourcePlan>> {
let mut incoming = self
.resources
.keys()
.cloned()
.map(|id| (id, 0_usize))
.collect::<IndexMap<_, _>>();
let mut outgoing: HashMap<ResourceId, Vec<ResourceId>> = HashMap::new();
for resource in self.resources.values() {
for dependency in &resource.depends_on {
let Some(count) = incoming.get_mut(&resource.id) else {
unreachable!("every resource was added to incoming")
};
if !self.resources.contains_key(dependency) {
bail!(
"bootstrap resource '{}' depends on missing resource '{}'",
resource.id,
dependency
);
}
*count += 1;
outgoing
.entry(dependency.clone())
.or_default()
.push(resource.id.clone());
}
}
let mut ready = incoming
.iter()
.filter_map(|(id, count)| (*count == 0).then_some(id.clone()))
.collect::<VecDeque<_>>();
let mut ordered = Vec::with_capacity(self.resources.len());View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Declare the missing resource named in the message, or remove the dependency on it
- If the dependency is conditional, filter it out of depends_on before insert when the target is absent
- Dump the plan (JSON output) and confirm the exact `kind:name` ids that exist — the reference must match exactly, including case
Example fix
// before
let mut plan = ResourcePlan::new(id, cur, want, action);
plan.depends_on.push(ResourceId::new("user", "alice")); // alice never inserted
bootstrap_plan.insert(plan)?;
// after
if users.contains_key("alice") {
plan.depends_on.push(ResourceId::new("user", "alice"));
}
bootstrap_plan.insert(plan)?; Defensive patterns
Strategy: validation
Validate before calling
// filter depends_on to resources that will actually be inserted
let valid_ids: std::collections::HashSet<&ResourceId> = declared.values().map(|r| &r.id).collect();
for resource in declared {
resource.depends_on.retain(|dep| valid_ids.contains(dep));
plan.insert(resource)?;
} Prevention
- Call plan.output() (as plan() itself does) before serializing — it validates all references and cycles
- When a dependency refers to an optional resource, add the edge only when that resource was declared
- Keep dependency ids as exact `kind:name` pairs matching declared resources — case-sensitive
When it happens
Trigger: A ResourcePlan inserted with a depends_on entry naming an id that is not in the plan (e.g. an account, file, or directory that was filtered out because its manager was unavailable or its section disabled); compose projects have their own earlier-specific message, so this generic one fires for the remaining wiring.
Common situations: Config referencing a resource that a disabled manager or excluded section would have provided; adapters emitting dependency edges for optional resources without checking presence.
Related errors
- cannot add dependency to missing bootstrap resource '{resour
- bootstrap plan contains resources with unknown state
- refusing unsafe change to bootstrap group '{}'; inspect `mis
- refusing unsafe change to bootstrap user '{}'; inspect `mise
- bootstrap resource '{}' is declared more than once
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/543f4dfe2869a511.
Report an issue: GitHub.