jdx/mise · error · eyre::Report

cannot add dependency to missing bootstrap resource '{resour

Error message

cannot add dependency to missing bootstrap resource '{resource}'

What it means

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.

Source

Thrown at src/system/resources.rs:139

pub struct BootstrapPlan {
    resources: IndexMap<ResourceId, ResourcePlan>,
}

impl BootstrapPlan {
    pub fn insert(&mut self, resource: ResourcePlan) -> Result<()> {
        if self.resources.contains_key(&resource.id) {
            bail!(
                "bootstrap resource '{}' is declared more than once",
                resource.id
            );
        }
        self.resources.insert(resource.id.clone(), resource);
        Ok(())
    }

    pub fn add_dependency(&mut self, resource: &ResourceId, dependency: ResourceId) -> Result<()> {
        let Some(resource) = self.resources.get_mut(resource) else {
            bail!("cannot add dependency to missing bootstrap resource '{resource}'");
        };
        if !resource.depends_on.contains(&dependency) {
            resource.depends_on.push(dependency);
        }
        Ok(())
    }

    pub fn output(&self) -> Result<BootstrapPlanOutput<'_>> {
        let resources = self.ordered()?;
        let mut summary = PlanSummary::default();
        for resource in &resources {
            summary.add(resource.action);
        }
        Ok(BootstrapPlanOutput { resources, summary })
    }

    fn ordered(&self) -> Result<Vec<&ResourcePlan>> {
        let mut incoming = self

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Insert the resource with plan.insert(...) before adding dependencies that point at it
  2. Check the id spelling: the error prints `kind:name` — it must match the inserted ResourceId exactly (kind and name, case-sensitive)
  3. If the resource can be legitimately absent (feature disabled), skip adding its dependency edges too

Example fix

// before
plan.add_dependency(&ResourceId::new("user", "alice"), ResourceId::new("group", "devs"))?;
plan.insert(alice_plan)?; // too late

// after
plan.insert(alice_plan)?;
plan.add_dependency(&ResourceId::new("user", "alice"), ResourceId::new("group", "devs"))?;
Defensive patterns

Strategy: validation

Validate before calling

// before adding an edge, confirm the dependent exists
if plan_contains(&plan, &resource_id) {
    plan.add_dependency(&resource_id, dependency)?;
} else {
    // skip or insert the resource first
}

fn plan_contains(plan: &BootstrapPlan, id: &ResourceId) -> bool {
    plan.output() // or expose a contains check; ids print as `kind:name`
        .map(|o| o.resources.iter().any(|r| &r.id == id))
        .unwrap_or(false)
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/2f645185e05d44fc. Report an issue: GitHub.