zed-industries/zed · error

no GPUI crates found in the workspace

Error message

no GPUI crates found in the workspace

What it means

This error is thrown by the xtask gpui crate-graph tool when it scans the cargo workspace for crates whose package names start with "gpui" and finds none. The tool builds a dependency graph rooted at all GPUI crates to compute release ordering; without any such crates the graph query has no roots, so the code fails fast with `ensure!` rather than proceeding with an empty graph. It indicates the workspace being analyzed is not the one containing the GPUI crates, or the workspace failed to load correctly.

Solutions

  1. Run the xtask from the repository root that contains the GPUI crates (the Zed workspace), so `cargo metadata` resolves the full workspace
  2. Verify the workspace members include crates named `gpui*` (check the root Cargo.toml members list and `cargo metadata --format-version 1 | grep '"name":"gpui'`)
  3. If running in CI or a sparse checkout, ensure the gpui crate directories are checked out and not excluded
  4. If crates were renamed/forked, restore the `gpui` name prefix or update the `name.starts_with("gpui")` filter in tooling/xtask/src/tasks/gpui/crate_graph.rs to match the new names
  5. Re-run the command in a clean build environment to rule out a stale or failed `cargo metadata` load

Example fix

// before (running from a sub-workspace)
cd crates/zed && cargo xtask release-deps
// after
cd /path/to/zed && cargo xtask release-deps
Defensive patterns

Strategy: validation

Validate before calling

let gpui_count = graph.workspace().iter_by_name().filter(|(name, _)| name.starts_with("gpui")).count();
if gpui_count == 0 {
    anyhow::bail!(
        "current workspace has no `gpui*` crates; run this xtask from the Zed repository root"
    );
}

Type guard

fn has_gpui_crates(graph: &cargo_metadata::Metadata) -> bool {
    graph.workspace().iter_by_name().any(|(name, _)| name.starts_with("gpui"))
}

Try / catch

match gpui_crates(&graph) {
    Ok(roots) => roots,
    Err(e) if e.to_string().contains("no GPUI crates found") => {
        eprintln!("wrong workspace: {e}; cd to the Zed repo root and retry");
        std::process::exit(1);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Running the gpui release/dependency xtask (e.g. via `selects_release_dependencies_in_topological_order` -> `gpui_crates`) against a workspace (set by CARGO env vars, --manifest-path, or cwd) that contains no packages named `gpui*` — e.g. running from a sub-workspace, wrong directory, a fork where crates were renamed, or after cargo metadata returned an empty/partial workspace.

Common situations: Invoking `cargo xtask` from the wrong checkout or a trimmed/vendored workspace; renaming gpui crates locally; running in CI with a sparse checkout that omits the gpui crates; a cargo metadata failure that silently yields no packages; pointing the tool at a different project's workspace.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of zed-industries/zed@916fc2b8cb (2026-09-19). Data as JSON: /api/errors/86020dbea64305ae. Report an issue: GitHub.

Appendix: source

Thrown at tooling/xtask/src/tasks/gpui/crate_graph.rs:22

    graph::{DependencyDirection, ExternalSource, PackageGraph, PackageSet, PackageSource},
};
use url::Url;

pub fn load_workspace_graph() -> Result<PackageGraph> {
    MetadataCommand::new()
        .build_graph()
        .context("failed to load the workspace crate graph")
}

/// Returns all GPUI crates in the current workspace
pub fn gpui_crates(graph: &PackageGraph) -> Result<PackageSet<'_>> {
    let roots = graph
        .workspace()
        .iter_by_name()
        .filter(|(name, _)| name.starts_with("gpui"))
        .map(|(_, package)| package.id())
        .collect::<Vec<_>>();
    ensure!(!roots.is_empty(), "no GPUI crates found in the workspace");

    let dependencies = graph
        .query_forward(roots)?
        // we do not need dev dependencies for releases
        .resolve_with_fn(|_, link| !link.dev_only());

    // Keep all workspace crates and Zed forks
    Ok(
        dependencies.filter(DependencyDirection::Reverse, |package| {
            package.in_workspace() || is_zed_fork(package.source())
        }),
    )
}

fn is_zed_fork(source: PackageSource<'_>) -> bool {
    let Some(ExternalSource::Git { repository, .. }) = source.parse_external() else {
        return false;
    };

View on GitHub (pinned to 916fc2b8cb)