{"record":{"id":"21ba23b16ea91f11","repo":"zeroclaw-labs/zeroclaw","slug":"unable-to-determine-installed-skill-directory-afte","errorCode":null,"errorMessage":"Unable to determine installed skill directory after clone (no new directory found)","messagePattern":"Unable to determine installed skill directory after clone \\(no new directory found\\)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-runtime/src/skills/mod.rs","lineNumber":1990,"sourceCode":"    Ok(paths)\n}\n\nfn detect_newly_installed_directory(\n    skills_path: &Path,\n    before: &HashSet<PathBuf>,\n) -> Result<PathBuf> {\n    let mut created = Vec::new();\n    for entry in std::fs::read_dir(skills_path)? {\n        let entry = entry?;\n        let path = entry.path();\n        if !before.contains(&path) && path.is_dir() {\n            created.push(path);\n        }\n    }\n\n    match created.len() {\n        1 => Ok(created.remove(0)),\n        0 => anyhow::bail!(\n            \"Unable to determine installed skill directory after clone (no new directory found)\"\n        ),\n        _ => anyhow::bail!(\n            \"Unable to determine installed skill directory after clone (multiple new directories found)\"\n        ),\n    }\n}\n\nfn enforce_skill_security_audit(\n    skill_path: &Path,\n    allow_scripts: bool,\n) -> Result<audit::SkillAuditReport> {\n    let report = audit::audit_skill_directory_with_options(\n        skill_path,\n        audit::SkillAuditOptions { allow_scripts },\n    )?;\n    if report.is_clean() {\n        return Ok(report);","sourceCodeStart":1972,"sourceCodeEnd":2008,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-runtime/src/skills/mod.rs#L1972-L2008","documentation":"install_git_skill_source snapshots the skills directory, runs 'git clone --depth 1 <source>' inside it, then detect_newly_installed_directory diffs before/after to locate the installed directory. Zero new directories means git reported success but nothing new appeared — most often because git cloned into a pre-existing empty directory that was already in the snapshot (git permits cloning into an existing empty dir).","triggerScenarios":"skills/<repo-name> already exists as an empty directory when the clone runs; the cloned directory is deleted concurrently between clone and scan; another process restructures the skills dir mid-install.","commonSituations":"A previous failed install left an empty directory behind; two installs racing in the same workspace; interrupted cleanup after an audit rejection removed the wrong residue.","solutions":["List the workspace skills/ directory and remove any leftover empty directory named after the repo being cloned, then retry the install","Run installs serially — never two skills install commands against the same workspace at once","If it persists, run 'git clone --depth 1 <url>' manually inside the skills dir to see what layout git produces"],"exampleFix":"# before: empty leftover dir 'my-skill' makes the diff find nothing new\nls skills/            # my-skill/ (empty)\n\n# after\nrmdir skills/my-skill && zeroclaw skills install <git-url>","handlingStrategy":"retry","validationCode":"// Before a git-source install, clear stale empty dirs named after the repo:\nlet repo_dir_name = source.trim_end_matches('/').rsplit('/').next()\n    .unwrap_or_default().trim_end_matches(\".git\");\nlet candidate = skills_path.join(repo_dir_name);\nif candidate.is_dir() && std::fs::read_dir(&candidate)?.next().is_none() {\n    std::fs::remove_dir(&candidate)?;\n}","typeGuard":null,"tryCatchPattern":"match install_git_skill_source(url, &skills_path, allow_scripts) {\n    Err(e) if e.to_string().contains(\"no new directory found\") => {\n        // clean leftover empty dirs in skills_path, then retry once\n    }\n    r => r,\n}","preventionTips":["Clean empty residue directories out of the skills dir after failed installs","Install serially within a workspace","On failure, inspect skills/ before retrying so the diff stays unambiguous"],"tags":["skills","install","git-clone","filesystem"],"backgroundTag":"clone-artifact-detection-failed","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}