Hmbown/CodeWhale · error
skill '{name}' is not installed at {}
Error message
skill '{name}' is not installed at {} What it means
uninstall() bails with this error when the skill's target directory under skills_dir does not exist; the check runs before any marker or removal logic. The resolved path is printed in the message, so name mismatches and wrong-directory cases are visible.
Source
Thrown at crates/tui/src/skills/install.rs:502
}
}
InstallOutcome::NeedsApproval(_) | InstallOutcome::NetworkDenied(_) => {}
}
match outcome {
InstallOutcome::Installed(installed) => Ok(UpdateResult::Updated(installed)),
InstallOutcome::NeedsApproval(host) => Ok(UpdateResult::NeedsApproval(host)),
InstallOutcome::NetworkDenied(host) => Ok(UpdateResult::NetworkDenied(host)),
}
}
/// Remove a community-installed skill.
///
/// Refuses to touch any directory that doesn't carry the `.installed-from`
/// marker — that's our cue that it's user-owned and not a system skill.
pub fn uninstall(name: &str, skills_dir: &Path) -> Result<()> {
let target = skill_target_path(name, skills_dir)?;
if !target.exists() {
bail!("skill '{name}' is not installed at {}", target.display());
}
ensure_target_within_skills_dir(&target, skills_dir)?;
if !target.join(INSTALLED_FROM_MARKER).exists() {
return Err(InstallError::NotInstalledHere(name.to_string()).into());
}
fs::remove_dir_all(&target)
.with_context(|| format!("failed to remove {}", target.display()))?;
Ok(())
}
/// Mark a community-installed skill as trusted, binding the marker to the
/// current package content digest (schema v2).
///
/// Refuses to mark system skills (no `.installed-from`) so the bundled
/// `skill-creator` doesn't accidentally inherit elevated tool privileges.
#[cfg(test)]
pub fn trust(name: &str, skills_dir: &Path) -> Result<()> {
let target = skill_target_path(name, skills_dir)?;View on GitHub (pinned to 0c42157ee5)
Solutions
- List installed skills and copy the exact, case-sensitive directory name.
- Compare the path in the error message against where the skill actually lives; the checked skills_dir is printed.
- If the directory exists but lacks the .installed-from marker, the sibling NotInstalledHere error applies: system/user-owned skills are not uninstallable this way.
Example fix
# before /skill uninstall MySkill # -> not installed at .../skills/MySkill # after (actual directory is my-skill) /skill uninstall my-skill
Defensive patterns
Strategy: validation
Validate before calling
let target = skills_dir.join(name);
if !target.exists() {
eprintln!("skill '{name}' not present under {}; nothing to uninstall", skills_dir.display());
return;
} Prevention
- List installed skills first and copy the exact case-sensitive directory name.
- Confirm which skills dir (project vs user) the session uses before uninstalling.
- Make bulk uninstall scripts skip missing names instead of aborting.
When it happens
Trigger: '/skill uninstall <name>' where the name was never installed, is spelled differently (skill directories are cased names), or the skill lives under a different skills_dir than the one in effect.
Common situations: Typos or case mismatches in the skill name, multiple skills directories (project vs user) with the skill in the other one, and stale memory after a skill was already removed.
Related errors
- plugin `{selector}` is enabled; disable it first with /plugi
- install source must not be empty
- github source must be 'github:owner/repo' (got {spec})
- skill '{name}' was imported locally (spec '{}') and cannot b
- invalid registry url: {registry_url}
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/dc7f3bc2d2b8017c.
Report an issue: GitHub.