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

  1. Run cargo clean without --target or other flags to do a full clean.
  2. Delete the target directory manually (rm -rf target/) and rebuild from scratch.
  3. Update cargo — older target directories may use layouts incompatible with newer clean logic.
  4. 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

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


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/4d571bcf1d0ce156.json. Report an issue: GitHub.