zeroclaw-labs/zeroclaw · error · anyhow::Error
invalid --skill name '{$skill}': use a bare skill name (lett
Error message
invalid --skill name '{$skill}': use a bare skill name (letters, digits, '-', '_') What it means
install_git_catalog_skill_source requires the skill name to satisfy is_registry_source: non-empty; no '/', '\\', '..', ':', or '://'; not starting with '.' or '~'; and only ASCII letters, digits, '-', '_'. Anything else — paths, URLs, scoped or relative specifiers — is rejected before any clone happens.
Source
Thrown at crates/zeroclaw-runtime/src/skills/mod.rs:2349
names.sort();
names
}
/// Install a single skill by name from a git catalog repository.
///
/// Clones `url` into a throwaway directory, resolves `skills/<skill_name>/`
/// (the same `<repo>/skills/<name>/` layout as the default and extra
/// registries), and installs it through the shared local-copy path (which
/// runs the security audit). No archive handling — pure `git clone`.
pub fn install_git_catalog_skill_source(
url: &str,
skill_name: &str,
skills_path: &Path,
allow_scripts: bool,
workspace_dir: &Path,
) -> Result<(PathBuf, usize)> {
if !is_registry_source(skill_name) {
anyhow::bail!(crate::i18n::get_required_cli_string_with_args(
"cli-skills-install-invalid-skill-name",
&[("skill", skill_name)]
));
}
std::fs::create_dir_all(workspace_dir).with_context(|| {
crate::i18n::get_required_cli_string_with_args(
"cli-skills-install-catalog-clone-failed",
&[("url", url)],
)
})?;
let clone_tempdir = tempfile::Builder::new()
.prefix(".skill-catalog-")
.tempdir_in(workspace_dir)
.with_context(|| {
crate::i18n::get_required_cli_string_with_args(
"cli-skills-install-catalog-clone-failed",
&[("url", url)],View on GitHub (pinned to 88bb9c8533)
Solutions
- Pass only the bare skill name (e.g. my-skill) and put the repository URL in the url argument
- Replace spaces, dots, and slashes with '-' or '_'
- For a local path or a whole-repo install, use the local-source or git-source install entry points instead of the catalog one
Example fix
// before install_git_catalog_skill_source(url, "owner/my-skill", &skills_path, false, &ws)?; // after install_git_catalog_skill_source(url, "my-skill", &skills_path, false, &ws)?;
Defensive patterns
Strategy: validation
Validate before calling
if !zeroclaw_runtime::skills::is_registry_source(skill_name) {
anyhow::bail!("skill name must be bare (letters, digits, '-', '_'): got {skill_name}");
}
install_git_catalog_skill_source(url, skill_name, &skills_path, allow_scripts, &workspace)?; Type guard
// is_registry_source is public and is the exact predicate the installer uses:
fn is_bare_skill_name(name: &str) -> bool {
zeroclaw_runtime::skills::is_registry_source(name)
} Prevention
- Validate names with the library's own is_registry_source before calling the catalog installer
- Keep catalog skill names to [A-Za-z0-9_-] by construction in your tooling
- Route paths and URLs to the local/git install entry points, never the catalog one
When it happens
Trigger: Passing 'owner/repo', 'https://...', './my-skill', 'registry:foo/bar', or a name containing spaces or dots as the skill-name argument of a catalog install.
Common situations: Confusing the catalog install (URL plus bare skill name) with the git install (URL only) or the local install (filesystem path).
Related errors
- Skill content is empty
- Skill content is missing YAML front-matter (expected `---` d
- Skill front-matter missing required `name` field
- Skill source must be a directory: {}
- skill '{$skill}' not found in {$url}: no skills/ directory,
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/400d411a57676bf5.
Report an issue: GitHub.