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
- Run the xtask from the repository root that contains the GPUI crates (the Zed workspace), so `cargo metadata` resolves the full workspace
- Verify the workspace members include crates named `gpui*` (check the root Cargo.toml members list and `cargo metadata --format-version 1 | grep '"name":"gpui'`)
- If running in CI or a sparse checkout, ensure the gpui crate directories are checked out and not excluded
- 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
- 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
- Always invoke the gpui xtasks from the repository root, not a sub-workspace
- Pre-check the workspace with `cargo metadata` before running release tooling
- In CI, verify the full checkout includes the gpui crate directories
- Keep gpui crate names stable (with the `gpui` prefix) when restructuring the workspace
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
- Cargo.toml not found in current directory. Please run this…
- Current directory does not appear to be a workspace root…
- Could not find package or crate named
- cross-arch clippy not supported for
- failed to build extension
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)