FuelLabs/sway · error · anyhow::Error
Failed to find path root: `path` dependency \"{}\" has no pa
Error message
Failed to find path root: `path` dependency \"{}\" has no parent What it means
find_path_root walks incoming edges upward from a node whose pinned source is Path; the loop assumes every path-sourced node has a parent (something depends on it). If a path-pinned node has no incoming edges, the walk cannot find a filesystem root and this error fires - a path dependency exists as a graph root, which is structurally invalid.
Source
Thrown at forc-pkg/src/pkg.rs:1339
"invalid `path_root` for path dependency package {:?}",
&graph[path_dep].name
)
}
Ok(())
}
/// Given any node in the graph, find the node that is the path root for that node.
fn find_path_root(graph: &Graph, mut node: NodeIx) -> Result<NodeIx> {
loop {
let pkg = &graph[node];
match pkg.source {
source::Pinned::Path(ref src) => {
let parent = graph
.edges_directed(node, Direction::Incoming)
.next()
.map(|edge| edge.source())
.ok_or_else(|| {
anyhow!(
"Failed to find path root: `path` dependency \"{}\" has no parent",
src
)
})?;
node = parent;
}
source::Pinned::Git(_)
| source::Pinned::Ipfs(_)
| source::Pinned::Member(_)
| source::Pinned::Registry(_) => {
return Ok(node);
}
}
}
}
/// Given an empty or partially completed `graph`, complete the graph.
///View on GitHub (pinned to 47e5e902fa)
Solutions
- Delete Forc.lock and rebuild so paths are re-derived from the manifests.
- Avoid editing Forc.lock by hand - change dependencies in Forc.toml and let forc regenerate.
- If it recurs from a clean state, report to FuelLabs/sway with the manifests and lock.
Example fix
# before forc build # Failed to find path root: `path` dependency "../lib" has no parent # after rm Forc.lock && forc build
Defensive patterns
Strategy: try-catch
Validate before calling
// every Path-pinned node must have at least one dependent (incoming edge)
for ix in graph.node_indices() {
if let forc_pkg::source::Pinned::Path(_) = graph[ix].source {
if graph.edges_directed(ix, petgraph::Direction::Incoming).next().is_none() {
// invalid structure: regenerate Forc.lock before building
}
}
} Try / catch
match build_plan_result {
Ok(plan) => { /* ... */ }
Err(e) if e.to_string().contains("Failed to find path root") => {
let _ = std::fs::remove_file(&lock_path);
// regenerate once; if it reproduces from a clean lock, report upstream
}
Err(e) => return Err(e),
} Prevention
- Never pin or reorder path entries by editing Forc.lock manually.
- After deleting a dependent package, regenerate the lock so orphaned path nodes are pruned.
When it happens
Trigger: A lock/graph where a Path-pinned package is a root node - e.g. Forc.lock hand-edited to pin the project itself as Path, or graph pruning removed a parent edge while leaving the child; typically not producible from well-formed manifests.
Common situations: Manually edited Forc.lock; artifacts of stale locks after removing dependents; forc-pkg regressions.
Related errors
- Couldn't find manifest file for {}
- failed to construct path for dependency {:?}: {}
- lock file did not match manifest
- graph contains no project node
- no entry in parent manifest
AI-assisted analysis of FuelLabs/sway@47e5e902fa (2026-08-16).
Data as JSON: /api/errors/74f2bdb623a617fb.
Report an issue: GitHub.