rust-lang/cargo · error · anyhow::Error
found a virtual manifest at `{}` instead of a package manife
Error message
found a virtual manifest at `{}` instead of a package manifest What it means
read_package expects a Cargo.toml containing a [package] table (a Real manifest). When it parses a virtual manifest — one that only declares [workspace] with no package — it cannot produce a Package, so it bails at cargo_read_manifest.rs:22. Virtual manifests describe a workspace root but are not themselves buildable/publishable.
Source
Thrown at src/ops/cargo_read_manifest.rs:22
use crate::util::errors::CargoResult;
use crate::workspace::parser::read_manifest;
use crate::workspace::{EitherManifest, Package, SourceId};
use tracing::trace;
pub fn read_package(
path: &Path,
source_id: SourceId,
gctx: &GlobalContext,
) -> CargoResult<Package> {
trace!(
"read_package; path={}; source-id={}",
path.display(),
source_id
);
let manifest = read_manifest(path, source_id, gctx)?;
let manifest = match manifest {
EitherManifest::Real(manifest) => manifest,
EitherManifest::Virtual(..) => anyhow::bail!(
"found a virtual manifest at `{}` instead of a package \
manifest",
path.display()
),
};
Ok(Package::new(manifest, path))
}
View on GitHub (pinned to 0e07a15537)
Solutions
- Target a specific member package with `-p <name>` or run the command from inside that member's directory.
- If you intended a single-package project, replace the virtual manifest with a real one by adding a [package] section.
- For programmatic callers, detect EitherManifest::Virtual before calling read_package and route to the workspace member list instead.
Example fix
# before (virtual workspace root) $ cargo publish error: found a virtual manifest at `./Cargo.toml` # after - publish a specific member $ cargo publish -p my-crate
Defensive patterns
Strategy: validation
Validate before calling
# Detect a virtual manifest before calling package-level ops: if grep -qE '^\[workspace\]' Cargo.toml && ! grep -qE '^\[package\]' Cargo.toml; then echo "virtual manifest: target a member with -p <name>" >&2 exit 1 fi
Prevention
- When scripting against a workspace, enumerate members and target one with -p.
- Do not assume the nearest Cargo.toml is a package manifest.
- Prefer `cargo metadata --no-deps` to discover packages programmatically.
When it happens
Trigger: Pointing a package-level operation (read_package, used by cargo package/publish/registry flows) at the workspace-root Cargo.toml of a multi-crate workspace that is virtual.
Common situations: Running `cargo publish` (without -p) at the root of a virtual workspace; tooling that walks up to the nearest Cargo.toml and assumes it is a package.
Related errors
- all dependencies must have a version requirement specified w
- package `{}` cannot be tested because it requires dev-depend
- {}package(s) `{}` not found in workspace `{}`
- no library targets found in packages: {}
- {}This may cause issue during packaging, as modules resoluti
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/0f36bd938493e129.json.
Report an issue: GitHub.