zeroclaw-labs/zeroclaw · error · anyhow::Error

Unable to determine installed skill directory after clone (m

Error message

Unable to determine installed skill directory after clone (multiple new directories found)

What it means

Same before/after directory diff in detect_newly_installed_directory, but two or more new directories appeared. git clone creates exactly one directory, so the extras came from something else writing into the skills directory between the snapshot and the scan.

Source

Thrown at crates/zeroclaw-runtime/src/skills/mod.rs:1993

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);
    }

    anyhow::bail!("Skill security audit failed: {}", report.summary());

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Serialize installs with a workspace-level lock or run them one at a time
  2. Inspect skills/ for the unexpected new directories, remove them if unwanted, and retry
  3. Identify what else writes into the workspace skills dir and pause it during installs
Defensive patterns

Strategy: validation

Validate before calling

// Serialize in-process installs:
static INSTALL_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
let _guard = INSTALL_LOCK.lock().unwrap_or_else(|p| p.into_inner());
install_git_skill_source(url, &skills_path, allow_scripts)?;

Try / catch

match install_git_skill_source(...) {
    Err(e) if e.to_string().contains("multiple new directories found") => {
        // list skills/ entries created after start, remove intruders, retry
    }
    r => r,
}

Prevention

When it happens

Trigger: Two concurrent skill installs into the same workspace; an agent loop, file watcher, or skill-improvement job creating directories under skills/ at the moment of the install.

Common situations: Parallel automation invoking skills install; a background process materializing skill directories while an install is in flight.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/3d7f0f2c101ea170. Report an issue: GitHub.