rust-lang/cargo · error · anyhow::Error
single file packages cannot be used as dependencies
Error message
single file packages cannot be used as dependencies
What it means
Raised in `SourceId::load` (src/workspace/source_id.rs:401) for a `SourceKind::Path` dependency whose resolved path is a single file (passes `is_embedded(&path) && path.is_file()`). Cargo's path dependencies must be a directory containing a `Cargo.toml`; a lone `.rs` file is only valid as an embedded/crate-root inside a package, never as an external dependency source.
Source
Thrown at src/workspace/source_id.rs:402
/// Returns `true` if this source from a Git repository.
pub fn is_git(self) -> bool {
matches!(self.inner.kind, SourceKind::Git(_))
}
/// Creates an implementation of `Source` corresponding to this ID.
pub fn load<'a>(self, gctx: &'a GlobalContext) -> CargoResult<Box<dyn Source + 'a>> {
trace!("loading SourceId; {}", self);
match self.inner.kind {
SourceKind::Git(..) => Ok(Box::new(GitSource::new(self, gctx)?)),
SourceKind::Path => {
let path = self
.inner
.url
.to_file_path()
.expect("path sources cannot be remote");
if crate::workspace::parser::is_embedded(&path) && path.is_file() {
anyhow::bail!("single file packages cannot be used as dependencies")
}
Ok(Box::new(PathSource::new(&path, self, gctx)))
}
SourceKind::Registry | SourceKind::SparseRegistry => {
Ok(Box::new(RegistrySource::remote(self, gctx)?))
}
SourceKind::LocalRegistry => {
let path = self
.inner
.url
.to_file_path()
.expect("path sources cannot be remote");
Ok(Box::new(RegistrySource::local(self, &path, gctx)))
}
SourceKind::Directory => {
let path = self
.inner
.urlView on GitHub (pinned to 0e07a15537)
Solutions
- Point the `path` at the directory containing the dependency's `Cargo.toml` (e.g. `path = "../my-lib"`).
- If you genuinely have a single-file crate, wrap it in a minimal package directory with its own `Cargo.toml`.
- Re-check the path is not accidentally resolving to a file via a glob or trailing filename.
Example fix
# before
[dependencies]
my-lib = { path = "./src/my_lib.rs" }
# after
[dependencies]
my-lib = { path = "./my-lib" } # directory containing Cargo.toml Defensive patterns
Strategy: validation
Validate before calling
fn is_valid_path_dep(p: &std::path::Path) -> bool {
p.is_dir() && p.join("Cargo.toml").exists()
}
// assert is_valid_path_dep(std::path::Path::new(dep_path)) before declaring the dependency Prevention
- Always point path dependencies at a directory containing Cargo.toml.
- Never reference a single .rs file as a dependency path.
- Validate path deps in a pre-build script.
When it happens
Trigger: Declaring a dependency with `path = "./src/lib.rs"` or any path that points at a file rather than a directory; `is_embedded` returns true for a path that also satisfies `is_file()`.
Common situations: Confusing Cargo's path deps (which take a directory) with the embedded `[lib] path = "src/lib.rs"` syntax; pointing at a single-file crate from another workspace; refactoring a sub-crate into a file and forgetting to update dependents.
Related errors
- dependency `{}` in package `{}` requires a `{}` artifact to
- patch `{}` version mismatch note: patch location contains {}
- failed to parse the version requirement `{}` for dependency
- no executable for `{}` found in PATH
- `{feature}` is unsupported when inferring the crate name, us
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/5e698ba46e9b31b9.json.
Report an issue: GitHub.