rust-lang/cargo · error
you can't generate a lockfile for an empty workspace.
Error message
you can't generate a lockfile for an empty workspace.
What it means
Thrown by `cargo update` when the workspace has zero members (`ws.members().count() == 0`). An empty workspace (only a virtual manifest with no member crates) has no dependencies to resolve, so Cargo cannot generate a meaningful lockfile.
Solutions
- Add at least one member crate to the workspace: list it under `members` in the root Cargo.toml.
- Run `cargo update` from inside a member crate's directory instead.
- Check that the `members` glob patterns actually match existing subdirectories.
Example fix
# Cargo.toml (before — empty workspace) [workspace] members = [] # After — add a member [workspace] members = ["my-crate"]
Defensive patterns
Strategy: validation
Validate before calling
fn workspace_has_members(ws: &cargo::core::Workspace) -> bool {
ws.members().count() > 0
} Prevention
- Ensure the workspace `members` list is non-empty and globs match real directories.
- Add at least one member crate before running `cargo update`.
- Run `cargo update` from within a member crate directory.
When it happens
Trigger: Running `cargo update` in a directory whose `Cargo.toml` is a virtual manifest with an empty or missing `members` list, or where all members have been removed.
Common situations: Setting up a new workspace and running `cargo update` before adding any member crates; temporarily removing all members during a refactor; a misconfigured `members` glob that matches nothing.
Related errors
- a Cargo.lock must exist for this command
- cannot the lock file because was passed to prevent…
- cannot override workspace dependency with
- cannot override `workspace.lints` in `lints`, either remove…
- cannot specify both recursive and precise simultaneously
AI-assisted analysis of rust-lang/cargo@98a09e7e7d (2026-08-11).
Data as JSON: /api/errors/2129f037e62f0f96.
Report an issue: GitHub.
Appendix: source
Thrown at src/ops/cargo_update.rs:58
&CliFeatures::new_all(true),
HasDevUnits::Yes,
previous_resolve,
None,
&[],
true,
)?;
ops::write_pkg_lockfile(ws, &mut resolve)?;
print_lockfile_changes(ws, previous_resolve, &resolve, &mut registry)?;
Ok(())
}
pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoResult<()> {
if opts.recursive && opts.precise.is_some() {
anyhow::bail!("cannot specify both recursive and precise simultaneously")
}
if ws.members().count() == 0 {
anyhow::bail!("you can't generate a lockfile for an empty workspace.")
}
// Updates often require a lot of modifications to the registry, so ensure
// that we're synchronized against other Cargos.
let _lock = ws
.gctx()
.acquire_package_cache_lock(CacheLockMode::DownloadExclusive)?;
let previous_resolve = match ops::load_pkg_lockfile(ws)? {
Some(resolve) => resolve,
None => {
match opts.precise {
None => return generate_lockfile(ws),
// Precise option specified, so calculate a previous_resolve required
// by precise package update later.
Some(_) => {
let mut registry = ws.package_registry()?;View on GitHub (pinned to 98a09e7e7d)