{"record":{"id":"f2494ce476580c21","repo":"FuelLabs/sway","slug":"graph-contains-more-than-one-project-node","errorCode":null,"errorMessage":"graph contains more than one project node","messagePattern":"graph contains more than one project node","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"forc-pkg/src/pkg.rs","lineNumber":896,"sourceCode":"/// yielding any nodes from the graph that might potentially be a project node.\nfn potential_proj_nodes<'a>(g: &'a Graph, proj_name: &'a str) -> impl 'a + Iterator<Item = NodeIx> {\n    member_nodes(g).filter(move |&n| g[n].name == proj_name)\n}\n\n/// Given a graph, find the project node.\n///\n/// This should be the only node that satisfies the following conditions:\n///\n/// - The package name matches `proj_name`\n/// - The node has no incoming edges, i.e. is not a dependency of another node.\nfn find_proj_node(graph: &Graph, proj_name: &str) -> Result<NodeIx> {\n    let mut potentials = potential_proj_nodes(graph, proj_name);\n    let proj_node = potentials\n        .next()\n        .ok_or_else(|| anyhow!(\"graph contains no project node\"))?;\n    match potentials.next() {\n        None => Ok(proj_node),\n        Some(_) => Err(anyhow!(\"graph contains more than one project node\")),\n    }\n}\n\n/// Checks if the toolchain version is in compliance with minimum implied by `manifest`.\n///\n/// If the `manifest` is a ManifestFile::Workspace, check all members of the workspace for version\n/// validation. Otherwise only the given package is checked.\nfn validate_version(member_manifests: &MemberManifestFiles) -> Result<()> {\n    for member_pkg_manifest in member_manifests.values() {\n        validate_pkg_version(member_pkg_manifest)?;\n    }\n    Ok(())\n}\n\n/// Check minimum forc version given in the package manifest file\n///\n/// If required minimum forc version is higher than current forc version return an error with\n/// upgrade instructions","sourceCodeStart":878,"sourceCodeEnd":914,"githubUrl":"https://github.com/FuelLabs/sway/blob/47e5e902faa42baf652dd6a0c88cd23390c1a614/forc-pkg/src/pkg.rs#L878-L914","documentation":"find_proj_node found two or more graph nodes with the project's name that have no incoming edges. The 'single root' invariant is broken: there are multiple root nodes claiming the same package name, so compilation order and root selection are ambiguous.","triggerScenarios":"Two workspace members with identical [project] name (both end up as roots); a path/registry dependency whose package name equals the project name and also sits at a root; duplicate member directories both listed in members.","commonSituations":"Copy-pasting a member folder for a new package and forgetting to change its name; renaming one member to another member's name; template reuse inside one workspace.","solutions":["Grep all member Forc.toml files for '[project]' and make every name unique.","Check the [workspace] members list does not include the same package twice (directly or via nested dirs).","If a dependency legitimately shares the name, rename your project or the dependency reference, then regenerate Forc.lock."],"exampleFix":"# before: two members with the same name\n# libs/a/Forc.toml -> name = \"utils\"\n# libs/b/Forc.toml -> name = \"utils\"\n\n# after\n# libs/b/Forc.toml -> name = \"utils_v2\" (and update dependents)","handlingStrategy":"validation","validationCode":"let mut seen = std::collections::HashSet::new();\nfor m in member_manifests.values() {\n    if !seen.insert(m.project.name.clone()) {\n        return Err(format!(\"duplicate member name: {}\", m.project.name));\n    }\n}","typeGuard":"fn member_names_are_unique(manifests: &forc_pkg::MemberManifestFiles) -> bool {\n    let mut seen = std::collections::HashSet::new();\n    manifests.values().all(|m| seen.insert(m.project.name.clone()))\n}","tryCatchPattern":null,"preventionTips":["Name every workspace member uniquely from day one.","When copying a member as a template, change [project] name before building."],"tags":["graph","workspace","duplicate","manifest"],"backgroundTag":null,"analyzedSha":"47e5e902faa42baf652dd6a0c88cd23390c1a614","analyzedAt":"2026-08-16T07:57:45.555Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}