zeroclaw-labs/zeroclaw · error · anyhow::Error
Unable to determine installed skill directory after clone (n
Error message
Unable to determine installed skill directory after clone (no new directory found)
What it means
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).
Source
Thrown at crates/zeroclaw-runtime/src/skills/mod.rs:1990
Ok(paths)
}
fn detect_newly_installed_directory(
skills_path: &Path,
before: &HashSet<PathBuf>,
) -> Result<PathBuf> {
let mut created = Vec::new();
for entry in std::fs::read_dir(skills_path)? {
let entry = entry?;
let path = entry.path();
if !before.contains(&path) && path.is_dir() {
created.push(path);
}
}
match created.len() {
1 => Ok(created.remove(0)),
0 => anyhow::bail!(
"Unable to determine installed skill directory after clone (no new directory found)"
),
_ => anyhow::bail!(
"Unable to determine installed skill directory after clone (multiple new directories found)"
),
}
}
fn enforce_skill_security_audit(
skill_path: &Path,
allow_scripts: bool,
) -> Result<audit::SkillAuditReport> {
let report = audit::audit_skill_directory_with_options(
skill_path,
audit::SkillAuditOptions { allow_scripts },
)?;
if report.is_clean() {
return Ok(report);View on GitHub (pinned to 88bb9c8533)
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
Example fix
# before: empty leftover dir 'my-skill' makes the diff find nothing new ls skills/ # my-skill/ (empty) # after rmdir skills/my-skill && zeroclaw skills install <git-url>
Defensive patterns
Strategy: retry
Validate before calling
// Before a git-source install, clear stale empty dirs named after the repo:
let repo_dir_name = source.trim_end_matches('/').rsplit('/').next()
.unwrap_or_default().trim_end_matches(".git");
let candidate = skills_path.join(repo_dir_name);
if candidate.is_dir() && std::fs::read_dir(&candidate)?.next().is_none() {
std::fs::remove_dir(&candidate)?;
} Try / catch
match install_git_skill_source(url, &skills_path, allow_scripts) {
Err(e) if e.to_string().contains("no new directory found") => {
// clean leftover empty dirs in skills_path, then retry once
}
r => r,
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unable to determine installed skill directory after clone (m
- Skill source must be a directory: {}
- Source path does not exist: {source}
- Destination skill already exists: {}
- Skill security audit failed: {}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/21ba23b16ea91f11.
Report an issue: GitHub.