rust-lang/cargo · error
artifact dep
Error message
artifact dep
What it means
This panic is in calc_script_deps_for_artifact_deps(), which builds compile units for artifact dependencies (deps declared with artifact = "bin" / "staticlib" / etc. in Cargo.toml). The loop on line 548 skips any dep where dep.artifact() is None, so by line 552 dep.artifact() is guaranteed Some. The .expect() asserts this invariant — if it fires, the control-flow guard above was bypassed.
Source
Thrown at src/compiler/unit_dependencies.rs:552
// This is essentially the same as `calc_artifact_deps`, but there are some
// subtle differences that require this to be implemented differently.
//
// Produce units that build all required artifact kinds (like binaries,
// static libraries, etc) with the correct compile target.
//
// Computing the compile target for artifact units is more involved as it has to handle
// various target configurations specific to artifacts, like `target = "target"` and
// `target = "<triple>"`, which makes knowing the root units compile target
// `root_unit_compile_target` necessary.
let root_unit_compile_target = unit_for.root_compile_kind();
let unit_for = UnitFor::new_host(/*host_features*/ true, root_unit_compile_target);
for (dep_pkg_id, deps) in state.deps(unit, script_unit_for) {
for dep in deps {
if dep.kind() != DepKind::Build || dep.artifact().is_none() {
continue;
}
let artifact_pkg = state.get(dep_pkg_id);
let artifact = dep.artifact().expect("artifact dep");
let resolved_artifact_compile_kind = artifact
.target()
.map(|target| target.to_resolved_compile_kind(root_unit_compile_target));
result.extend(artifact_targets_to_unit_deps(
unit,
unit_for.with_artifact_features_from_resolved_compile_kind(
resolved_artifact_compile_kind,
),
state,
resolved_artifact_compile_kind.unwrap_or(CompileKind::Host),
artifact_pkg,
dep,
)?);
}
}
Ok(result)View on GitHub (pinned to 0e07a15537)
Solutions
- Update cargo to a version that stabilizes or fixes artifact-dependency handling.
- Remove the artifact dependency temporarily and verify the build succeeds without it, confirming it is the trigger.
- Regenerate Cargo.lock (rm Cargo.lock && cargo generate-lockfile) to ensure consistent dependency metadata.
- File a cargo bug with the minimal Cargo.toml reproducer using the artifact dep syntax.
Defensive patterns
Strategy: validation
Validate before calling
// Before relying on artifact deps, verify each dep's artifact field
for (dep_pkg_id, deps) in state.deps(unit, unit_for) {
for dep in deps {
if dep.kind() == DepKind::Build && dep.artifact().is_some() {
// safe to call dep.artifact().unwrap()
}
}
} Prevention
- Keep artifact dependency declarations simple and well-formed in Cargo.toml.
- Regenerate Cargo.lock after changing artifact deps to ensure consistent metadata.
- Test artifact deps on the latest nightly/stable cargo before relying on them in CI.
When it happens
Trigger: Having an artifact dependency (e.g., [dependencies] foo = { version = "1", artifact = "bin" }) where the dependency's artifact field was cleared or mutated between the is_none() check on line 548 and the expect on line 552 — which would require a data race or interior mutation bug in cargo's dependency model.
Common situations: Using artifact dependencies (a -Z unstable feature) with a cargo version that has a known bug in its dependency-resolution pipeline; concurrent or re-entrant calls into the unit-dependency graph builder; corrupted Cargo.lock or manifest causing inconsistent dep metadata.
Related errors
- env var was not array
- artifact-dir was not locked
- already loaded config values
- was not filled at beginning of the function
- len() == 1 above
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/7109f84ddec95c5c.json.
Report an issue: GitHub.