sinelaw/fresh · error

Plugin ' ' depends on ' ', which is not installed or not…

Error message

Plugin '{}' depends on '{}', which is not installed or not enabled

What it means

During dependency resolution, `topological_sort_plugins` found a plugin whose declared dependency is absent from the plugin map (not installed, or installed but disabled). It fails fast with both names so the misconfiguration is obvious rather than loading a partial graph.

Solutions

  1. Install or enable the named dependency plugin listed in the message.
  2. Fix the dependency name typo in the depending plugin's metadata/config.
  3. Remove the dependency entry if it is no longer needed.

Example fix

// before (config)
plugins = [{ name = "a", deps = ["b"] }] // b missing
// after
plugins = [
  { name = "b" },
  { name = "a", deps = ["b"] },
]
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check: every declared dep exists in the enabled plugin map
for p in &plugins {
    for dep in &p.deps {
        assert!(plugins.iter().any(|q| &q.name == dep), "missing dep {} for {}", dep, p.name);
    }
}

Try / catch

match topological_sort_plugins(&plugins) {
    Err(e) if e.to_string().contains("not installed or not enabled") => fix_config_and_retry(),
    other => other?,
}

Prevention

When it happens

Trigger: Calling `topological_sort_plugins` with a plugin set where plugin A lists plugin B in its dependencies but B is missing, disabled, or renamed.

Common situations: Config lists a plugin that was removed/renamed; a plugin enabled in config whose dependency is not in the plugins directory; typo in a dependency name.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13). Data as JSON: /api/errors/a7b6d6786148b625. Report an issue: GitHub.

Appendix: source

Thrown at crates/fresh-parser-js/src/lib.rs:223

    let mut in_degree: HashMap<&str, usize> = HashMap::new();
    let mut dependents: HashMap<&str, Vec<&str>> = HashMap::new();

    for name in plugin_names {
        in_degree.entry(name.as_str()).or_insert(0);
    }

    for name in plugin_names {
        if let Some(deps) = dependencies.get(name) {
            for dep in deps {
                // Only count dependencies on plugins that exist in our set
                if in_degree.contains_key(dep.as_str()) {
                    *in_degree.entry(name.as_str()).or_insert(0) += 1;
                    dependents
                        .entry(dep.as_str())
                        .or_default()
                        .push(name.as_str());
                } else {
                    return Err(anyhow!(
                        "Plugin '{}' depends on '{}', which is not installed or not enabled",
                        name,
                        dep
                    ));
                }
            }
        }
    }

    // Kahn's algorithm
    let mut queue: Vec<&str> = in_degree
        .iter()
        .filter(|(_, &deg)| deg == 0)
        .map(|(&name, _)| name)
        .collect();
    // Sort the initial queue alphabetically for determinism
    queue.sort();

View on GitHub (pinned to 67894ca546)