{"record":{"id":"86020dbea64305ae","repo":"zed-industries/zed","slug":"no-gpui-crates-found-in-the-workspace","errorCode":null,"errorMessage":"no GPUI crates found in the workspace","messagePattern":"no GPUI crates found in the workspace","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tooling/xtask/src/tasks/gpui/crate_graph.rs","lineNumber":22,"sourceCode":"    graph::{DependencyDirection, ExternalSource, PackageGraph, PackageSet, PackageSource},\n};\nuse url::Url;\n\npub fn load_workspace_graph() -> Result<PackageGraph> {\n    MetadataCommand::new()\n        .build_graph()\n        .context(\"failed to load the workspace crate graph\")\n}\n\n/// Returns all GPUI crates in the current workspace\npub fn gpui_crates(graph: &PackageGraph) -> Result<PackageSet<'_>> {\n    let roots = graph\n        .workspace()\n        .iter_by_name()\n        .filter(|(name, _)| name.starts_with(\"gpui\"))\n        .map(|(_, package)| package.id())\n        .collect::<Vec<_>>();\n    ensure!(!roots.is_empty(), \"no GPUI crates found in the workspace\");\n\n    let dependencies = graph\n        .query_forward(roots)?\n        // we do not need dev dependencies for releases\n        .resolve_with_fn(|_, link| !link.dev_only());\n\n    // Keep all workspace crates and Zed forks\n    Ok(\n        dependencies.filter(DependencyDirection::Reverse, |package| {\n            package.in_workspace() || is_zed_fork(package.source())\n        }),\n    )\n}\n\nfn is_zed_fork(source: PackageSource<'_>) -> bool {\n    let Some(ExternalSource::Git { repository, .. }) = source.parse_external() else {\n        return false;\n    };","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/zed-industries/zed/blob/916fc2b8cb3a815cbef4a3b40e13081be72036b6/tooling/xtask/src/tasks/gpui/crate_graph.rs#L4-L40","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before (running from a sub-workspace)\ncd crates/zed && cargo xtask release-deps\n// after\ncd /path/to/zed && cargo xtask release-deps","handlingStrategy":"validation","validationCode":"let gpui_count = graph.workspace().iter_by_name().filter(|(name, _)| name.starts_with(\"gpui\")).count();\nif gpui_count == 0 {\n    anyhow::bail!(\n        \"current workspace has no `gpui*` crates; run this xtask from the Zed repository root\"\n    );\n}","typeGuard":"fn has_gpui_crates(graph: &cargo_metadata::Metadata) -> bool {\n    graph.workspace().iter_by_name().any(|(name, _)| name.starts_with(\"gpui\"))\n}","tryCatchPattern":"match gpui_crates(&graph) {\n    Ok(roots) => roots,\n    Err(e) if e.to_string().contains(\"no GPUI crates found\") => {\n        eprintln!(\"wrong workspace: {e}; cd to the Zed repo root and retry\");\n        std::process::exit(1);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["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"],"tags":["cargo","workspace","build-tooling","xtask"],"backgroundTag":"empty-result-set","analyzedSha":"916fc2b8cb3a815cbef4a3b40e13081be72036b6","analyzedAt":"2026-09-19T19:09:50.599Z","contentChangedAt":"2026-09-19T19:09:50.599Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}