rust-lang/cargo · error
artifact-dir was not locked during clean
Error message
artifact-dir was not locked during clean
What it means
This panic fires during cargo clean when computing the artifact output directory for uplifted files. The code calls layout.artifact_dir().expect("artifact-dir was not locked during clean"). The artifact_dir() method returns Option<&ArtifactDirLayout> — it is None when the artifact-dir layout was not initialized. During a clean of artifact-producing targets, the layout must have an artifact-dir.
Source
Thrown at src/ops/cargo_clean.rs:297
// Remove the uplifted copy.
for target in pkg.targets() {
if target.is_custom_build() {
continue;
}
let crate_name: Rc<str> = target.crate_name().into();
for &mode in &[
CompileMode::Build,
CompileMode::Test,
CompileMode::Check { test: false },
] {
for (compile_kind, layout) in &layouts {
let triple = target_data.short_name(compile_kind);
let (file_types, _unsupported) = target_data
.info(*compile_kind)
.rustc_outputs(mode, target.kind(), triple, clean_ctx.gctx)?;
let artifact_dir = layout
.artifact_dir()
.expect("artifact-dir was not locked during clean");
let uplift_dir = match target.kind() {
TargetKind::ExampleBin | TargetKind::ExampleLib(..) => {
Some(artifact_dir.examples())
}
// Tests/benchmarks are never uplifted.
TargetKind::Test | TargetKind::Bench => None,
_ => Some(artifact_dir.dest()),
};
if let Some(uplift_dir) = uplift_dir {
for file_type in file_types {
let uplifted_filename = file_type.uplift_filename(target);
// Dep-info generated by Cargo itself.
let dep_info = Path::new(&uplifted_filename)
.with_extension("d")
.to_string_lossy()
.into_owned();
View on GitHub (pinned to 0e07a15537)
Solutions
- Run cargo clean without --target or other flags to do a full clean.
- Delete the target directory manually (rm -rf target/) and rebuild from scratch.
- Update cargo — older target directories may use layouts incompatible with newer clean logic.
- If using CARGO_TARGET_DIR or artifact-dir config, ensure the configuration is consistent across builds.
Defensive patterns
Strategy: fallback
Validate before calling
// Before cargo clean, verify target dir layout is consistent
let target_dir = std::path::Path::new("target");
if !target_dir.exists() {
println!("target directory does not exist; nothing to clean");
} Prevention
- Run cargo clean without extra flags for a full clean.
- If cargo clean panics, manually remove the target directory: rm -rf target/.
- Keep CARGO_TARGET_DIR and artifact-dir configuration consistent across builds.
- Avoid mixing cargo versions against the same target directory.
When it happens
Trigger: Running cargo clean on a target directory where the build layout was initialized without an artifact-dir (e.g., the build used a legacy layout or the artifact-dir feature was not engaged), but the clean code path iterates targets that expect artifact output locations.
Common situations: Cleaning a target directory left over from an older cargo version that used a different layout; running cargo clean --target with a configuration that doesn't set up artifact-dir; target directory manually modified or partially deleted leaving inconsistent layout state.
Related errors
- artifact-dir was not locked
- artifact dep
- already loaded config values
- env var was not array
- was not filled at beginning of the function
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/4d571bcf1d0ce156.json.
Report an issue: GitHub.