FuelLabs/sway · error
found dep {} without node entry in graph
Error message
found dep {} without node entry in graph What it means
Lock::to_graph works in two passes: first every [[package]] entry becomes a graph node keyed by '<name> <source>' (or just the name when unambiguous), then every dependency line is looked up in that key map. This error means a dependency line references a key that has no matching package entry - the lock's edges are inconsistent with its node list.
Source
Thrown at forc-pkg/src/lock.rs:224
.as_ref()
.into_iter()
.flatten()
.map(|contract_dep| (contract_dep, UnparsedDepKind::Contract));
// If `pkg.dependencies` is None, we will be collecting an empty list of
// lib_deps so that we will omit them during edge adding phase
let lib_deps = pkg
.dependencies
.as_ref()
.into_iter()
.flatten()
.map(|lib_dep| (lib_dep, UnparsedDepKind::Library));
for (dep_line, dep_kind) in lib_deps.chain(contract_deps) {
let (dep_name, dep_key, dep_salt) = parse_pkg_dep_line(dep_line)
.map_err(|e| anyhow!("failed to parse dependency \"{}\": {}", dep_line, e))?;
let dep_node = pkg_to_node
.get(dep_key)
.copied()
.ok_or_else(|| anyhow!("found dep {} without node entry in graph", dep_key))?;
let dep_name = dep_name.unwrap_or(&graph[dep_node].name).to_string();
let dep_kind = match dep_kind {
UnparsedDepKind::Library => DepKind::Library,
UnparsedDepKind::Contract => {
let dep_salt = dep_salt.unwrap_or_default();
DepKind::Contract { salt: dep_salt }
}
};
let dep_edge = Edge::new(dep_name, dep_kind);
graph.update_edge(node, dep_node, dep_edge);
}
}
Ok(graph)
}
/// Create a diff between `self` and the `old` `Lock`.
///View on GitHub (pinned to 47e5e902fa)
Solutions
- Delete Forc.lock and rebuild so the package table and dependency edges are regenerated together.
- When hand-fixing, ensure the dependency line's name and source exactly equal the target [[package]] entry's name and source.
- Treat Forc.lock as generated: resolve dependency conflicts in Forc.toml (or git ours/theirs on the lock) and regenerate.
Defensive patterns
Strategy: fallback
Validate before calling
// Rust, consistency pre-check: every dep-line key must exist among package keys. // Build both sets as '<name> <source>' (or bare name when unambiguous) and diff them, // surfacing missing entries before calling to_graph.
Try / catch
// Inconsistent lock -> regenerate rather than patch edges:
match lock.to_graph() {
Ok(g) => { /* ... */ }
Err(_) => { fs::remove_file(lock_path).ok(); /* rebuild plan from manifests */ }
} Prevention
- Regenerate Forc.lock wholesale after dependency or merge changes.
- If hand-fixing, keep dependency lines and package entries exactly name+source matched.
- Beware duplicate package names: disambiguation makes key mismatches easy to introduce.
When it happens
Trigger: A Forc.lock where a package's dependency line (name plus source) does not exactly match any [[package]] entry - typically a merge kept the dependency line but dropped or altered the target package entry, or a hand edit changed one side (name or source) without updating the other.
Common situations: Git merges of Forc.lock resolving to an inconsistent mix of both sides; renames of dependencies; two packages sharing a name where disambiguation keys (name+source) diverge between the edge and node sections.
Related errors
- failed to read {}: {}
- invalid 'source' entry for package {} lock: {:?}
- failed to parse dependency "{}": {}
- missing closing parenthesis
- missing pkg string
AI-assisted analysis of FuelLabs/sway@47e5e902fa (2026-08-16).
Data as JSON: /api/errors/b7dc0b796f307aa8.
Report an issue: GitHub.