jdx/mise · error

dependent resource is present

Error message

dependent resource is present

What it means

A Kahn topological-sort invariant panic in resource ordering: when decrementing a dependent's incoming-edge count, the code expects the dependent's entry to exist in the incoming-count map. The expect fires only if the graph maps are inconsistent — a dependent edge exists in `outgoing` but the corresponding node has no entry in `incoming`.

Solutions

  1. Verify every ID appearing in outgoing edges also gets an incoming entry when the graph is built
  2. Check that all declared resources are registered into the graph before sorting (no skipped/filtered nodes)
  3. Add a graph-construction validation that fails with a clear message on dangling dependency references
  4. If a dependency is optional, filter outgoing edges to known IDs when building `incoming`

Example fix

// before
let dependents = outgoing.get(&id);
// after
let dependents = outgoing.get(&id).filter(|ds| ds.iter().all(|d| incoming.contains_key(d)));
Defensive patterns

Strategy: validation

Validate before calling

for (id, deps) in &outgoing {
    for d in deps {
        assert!(incoming.contains_key(d), "dangling dependency {d} -> not in incoming map");
    }
}

Type guard

fn graph_consistent(g: &Graph) -> bool {
    g.outgoing.values().flatten().all(|d| g.incoming.contains_key(d))
}

Try / catch

let order = sorter.order().map_err(|e| anyhow!("resource graph invalid: {e}"))?;

Prevention

When it happens

Trigger: Building a resource graph where a dependency edge is recorded (outgoing) but the dependent node's in-degree was never registered (missing from `incoming`) — e.g. resources referencing each other without being declared, or partial graph construction after deserialization changes.

Common situations: Config files declaring resource dependencies (`depends`) on resource IDs that are defined but were skipped during graph-node registration, or plugin-supplied resource graphs with dangling edges.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/1867baf720c48a7d. Report an issue: GitHub.

Appendix: source

Thrown at src/system/resources.rs:302

                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());
        while let Some(id) = ready.pop_front() {
            ordered.push(&self.resources[&id]);
            if let Some(dependents) = outgoing.get(&id) {
                for dependent in dependents {
                    let count = incoming
                        .get_mut(dependent)
                        .expect("dependent resource is present");
                    *count -= 1;
                    if *count == 0 {
                        ready.push_back(dependent.clone());
                    }
                }
            }
        }

        if ordered.len() != self.resources.len() {
            let cycle = incoming
                .into_iter()
                .filter_map(|(id, count)| (count > 0).then_some(id.to_string()))
                .collect::<Vec<_>>()
                .join(", ");
            bail!("bootstrap resource dependency cycle: {cycle}");
        }
        Ok(ordered)
    }

View on GitHub (pinned to 533346cc37)