FuelLabs/sway · error · anyhow::Error

Cannot found project node in the graph

Error message

Cannot found project node in the graph

What it means

When building a single selected package (a manifest at a given path rather than the whole workspace), forc matches that manifest's directory and then looks up its project name among the build plan's member nodes via find_member_index. If the name is not found, the selected manifest is not a member of the resolved plan and this error is returned.

Source

Thrown at forc-pkg/src/pkg.rs:2263

    let build_plan = BuildPlan::from_pkg_opts(&build_options.pkg)?;
    let graph = build_plan.graph();
    let manifest_map = build_plan.manifest_map();

    // Check if manifest used to create the build plan is one of the member manifests or a
    // workspace manifest.
    let curr_manifest = manifest_map
        .values()
        .find(|&pkg_manifest| pkg_manifest.dir() == path);
    let build_profiles: HashMap<String, BuildProfile> = build_plan.build_profiles().collect();
    // Get the selected build profile using build options
    let build_profile = build_profile_from_opts(&build_profiles, build_options)?;
    // If this is a workspace we want to have all members in the output.
    let outputs = match curr_manifest {
        Some(pkg_manifest) => std::iter::once(
            build_plan
                .find_member_index(&pkg_manifest.project.name)
                .ok_or_else(|| anyhow!("Cannot found project node in the graph"))?,
        )
        .collect(),
        None => build_plan.member_nodes().collect(),
    };

    let outputs = member_filter.filter_outputs(&build_plan, outputs);

    // Build it!
    let mut built_workspace = Vec::new();
    let build_start = std::time::Instant::now();
    let built_packages = build(
        &build_plan,
        *build_target,
        &build_profile,
        &outputs,
        experimental,
        no_experimental,
        callback_handler,

View on GitHub (pinned to 47e5e902fa)

Solutions

  1. Open the Forc.toml at the path you passed and confirm its [project] name; confirm that name is resolvable as a member of the workspace (listed in members or auto-included)
  2. Build from the workspace root without --path to see which members forc actually resolves
  3. Fix [workspace] include/exclude globs so the package is included
  4. Check for duplicate member names after a rename that shadow each other

Example fix

# before: package renamed in its own Forc.toml
[project]
name = "new_name"
# workspace Forc.toml still uses the old dir/name

# after: keep workspace members and project names in sync
[workspace]
members = ["packages/new_name"]
Defensive patterns

Strategy: validation

Validate before calling

use forc_pkg::{BuildPlan, pkg::BuildOptions};

fn selected_pkg_is_member(manifest_name: &str, plan: &BuildPlan) -> bool {
    plan.member_nodes()
        .any(|ix| plan.graph()[ix].name == manifest_name)
}

// before calling build_with_options with a --path manifest:
// assert selected_pkg_is_member(&manifest.project.name, &plan);

Prevention

When it happens

Trigger: Calling the build API (or forc build --path ...) with a package whose [project].name is not among the resolved workspace members - because of a rename, an exclude pattern, or pointing at a package outside the workspace.

Common situations: Renaming a member in its Forc.toml while scripts/CI still reference the old path; [workspace] include/exclude globs that silently drop the package; nested workspaces resolving to the wrong root.

Related errors


AI-assisted analysis of FuelLabs/sway@47e5e902fa (2026-08-16). Data as JSON: /api/errors/f2307538987a5574. Report an issue: GitHub.