rust-lang/cargo · error

failed to find a workspace root

Error message

failed to find a workspace root

What it means

Thrown during inheritable-field resolution when a workspace member has no explicit root path (WorkspaceConfig::Member { root: None }) and the filesystem walk via find_workspace_root failed to locate an ancestor Cargo.toml containing a [workspace] section. The member expected to inherit fields from a workspace root but none could be found, so inheritance cannot proceed.

Solutions

  1. Ensure an ancestor directory contains a Cargo.toml with a [workspace] table that lists (or globs) this crate in its members.
  2. If the crate is standalone, remove all workspace-inherited fields (workspace = true, workspace.package.* references).
  3. Run cargo from the workspace root, or fix the member's relative root path if it uses WorkspaceConfig::Member { root: Some(..) }.
  4. Verify the directory structure: the member must be nested inside the workspace root.

Example fix

# before: member Cargo.toml references workspace inheritance
[package]
version.workspace = true
# but no ancestor has [workspace]

# after: add a workspace root Cargo.toml above this crate
# root Cargo.toml:
[workspace]
members = ["member-crate"]

[workspace.package]
version = "0.1.0"
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_workspace_root_accessible(member_path: &Path) -> Result<PathBuf, String> {
    let mut dir = member_path.parent().ok_or("no parent")?;
    loop {
        let cargo_toml = dir.join("Cargo.toml");
        if cargo_toml.is_file() {
            if let Ok(contents) = std::fs::read_to_string(&cargo_toml) {
                if contents.contains("[workspace]") {
                    return Ok(cargo_toml);
                }
            }
        }
        dir = dir.parent().ok_or("no workspace root found above this member")?;
    }
}

Type guard

fn has_workspace_root_above(path: &Path) -> bool {
    let mut dir = path.parent();
    while let Some(d) = dir {
        let f = d.join("Cargo.toml");
        if f.is_file() {
            if let Ok(c) = std::fs::read_to_string(&f) {
                if c.contains("[workspace]") { return true; }
            }
        }
        dir = d.parent();
    }
    false
}

Prevention

When it happens

Trigger: A crate declares itself a workspace member (or inherits workspace fields) but is not located under any directory containing a [workspace] Cargo.toml. find_workspace_root walks up from the member's normalized path and returns None, so inheritable_from_path is never called.

Common situations: A crate is moved out of its workspace without updating its manifest. A [workspace] members glob does not cover the crate's directory, yet the crate references workspace.package.* fields. Running cargo from a vendored/copied tree missing the workspace root. A member's Cargo.toml has workspace-inherited fields but no [workspace] ancestor exists.

Related errors


AI-assisted analysis of rust-lang/cargo@98a09e7e7d (2026-08-11). Data as JSON: /api/errors/6709f02018c180bc. Report an issue: GitHub.

Appendix: source

Thrown at src/workspace/parser/mod.rs:1002

    workspace_config: &WorkspaceConfig,
) -> CargoResult<InheritableFields> {
    match workspace_config {
        WorkspaceConfig::Root(root) => Ok(root.inheritable().clone()),
        WorkspaceConfig::Member {
            root: Some(path_to_root),
        } => {
            let path = normalized_path
                .parent()
                .unwrap()
                .join(path_to_root)
                .join("Cargo.toml");
            let root_path = paths::normalize_path(&path);
            inheritable_from_path(gctx, root_path)
        }
        WorkspaceConfig::Member { root: None } => {
            match find_workspace_root(&normalized_path, gctx)? {
                Some(path_to_root) => inheritable_from_path(gctx, path_to_root),
                None => Err(anyhow!("failed to find a workspace root")),
            }
        }
    }
}

fn inheritable_from_path(
    gctx: &GlobalContext,
    workspace_path: PathBuf,
) -> CargoResult<InheritableFields> {
    // Workspace path should have Cargo.toml at the end
    let workspace_path_root = workspace_path.parent().unwrap();

    // Let the borrow exit scope so that it can be picked up if there is a need to
    // read a manifest
    if let Some(ws_root) = gctx.ws_roots().get(workspace_path_root) {
        return Ok(ws_root.inheritable().clone());
    };

View on GitHub (pinned to 98a09e7e7d)