{"id":"4b1747e7242af223","repo":"rust-lang/cargo","slug":"cannot-clean-err","errorCode":null,"errorMessage":"cannot clean `{}`: {err}","messagePattern":"cannot clean `(.+?)`: (.+?)","errorType":"exception","errorClass":"AlreadyPrintedError","httpStatus":null,"severity":"error","filePath":"src/ops/cargo_clean.rs","lineNumber":87,"sourceCode":"            return Err(crate::AlreadyPrintedError::new(anyhow::anyhow!(\"\")).into());\n        }\n    }\n\n    // do some validation on target_dir if it was specified via --target-dir\n    if opts.explicit_target_dir_arg {\n        let target_dir_path = target_dir.as_path_unlocked();\n\n        // perform validation on target_dir only if it exists and check if the target directory has a valid CACHEDIR.TAG\n        if target_dir_path.exists()\n            && let Err(err) = validate_target_dir_tag(target_dir_path)\n        {\n            // if target_dir was passed explicitly via --target-dir, then hard error if validation fails\n            let title = format!(\"cannot clean `{}`: {err}\", target_dir_path.display());\n            let report = [Level::ERROR\n                .primary_title(title)\n                .element(Level::NOTE.message(CLEAN_ABORT_NOTE))];\n            gctx.shell().print_report(&report, false)?;\n            return Err(crate::AlreadyPrintedError::new(anyhow::anyhow!(\"\")).into());\n        }\n    }\n\n    if opts.doc {\n        if !opts.spec.is_empty() {\n            // FIXME: https://github.com/rust-lang/cargo/issues/8790\n            // This should support the ability to clean specific packages\n            // within the doc directory. It's a little tricky since it\n            // needs to find all documentable targets, but also consider\n            // the fact that target names might overlap with dependency\n            // names and such.\n            bail!(\"--doc cannot be used with -p\");\n        }\n        // If the doc option is set, we just want to delete the doc directory.\n        target_dir = target_dir.join(\"doc\");\n        clean_ctx.remove_paths(&[target_dir.into_path_unlocked()])?;\n    } else {\n        let profiles = Profiles::new(&ws, opts.requested_profile)?;","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/ops/cargo_clean.rs#L69-L105","documentation":"When `--target-dir` is passed explicitly, `cargo clean` validates that the directory is genuinely a cargo target dir by checking its `CACHEDIR.TAG` file. If `validate_target_dir_tag` returns an error (missing file, invalid signature, symlinked tag), cleaning is aborted with the failure reason and the standard \"cleaning has been aborted to prevent accidental deletion\" note. This prevents `cargo clean --target-dir <random-dir>` from nuking unrelated directories.","triggerScenarios":"`cargo clean --target-dir <path>` where `<path>` lacks a valid `CACHEDIR.TAG`, e.g. an arbitrary user directory, an empty dir, or one whose tag file has the wrong signature.","commonSituations":"Pointing `--target-dir` at a project's `dist/` or `out/` folder, a typo in the path, or a directory that was created by a non-cargo tool.","solutions":["Confirm the directory is really a cargo target dir (it should contain `CACHEDIR.TAG` with the canonical signature).","Run `cargo clean` *without* `--target-dir` to clean the default target dir, or rebuild in the explicit dir first so the tag is regenerated.","If the directory is stale, delete it manually (`rm -rf <dir>`) outside of cargo."],"exampleFix":"# before\ncargo clean --target-dir ./out   # ./out has no CACHEDIR.TAG\n\n# after (clean the real target dir)\ncargo clean","handlingStrategy":"validation","validationCode":"// When using --target-dir, ensure it carries a valid CACHEDIR.TAG before cleaning.\nuse std::path::Path;\nconst SIG: &[u8] = b\"Signature: 8a477f597d28d172789f06886806bc55\";\nfn is_cargo_target_dir(path: &Path) -> bool {\n    let tag = path.join(\"CACHEDIR.TAG\");\n    !tag.is_symlink() && tag.is_file() && std::fs::read(&tag).map(|b| b.starts_with(SIG)).unwrap_or(false)\n}\n// if !is_cargo_target_dir(&dir) { return Err(\"not a cargo target dir\".into()); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only pass `--target-dir` to directories cargo itself created.","Prefer the default target dir unless you have a strong reason to relocate.","Delete stale non-cargo directories manually rather than via `cargo clean`."],"tags":["cargo-clean","target-dir","validation","safety"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}