screenpipe/screenpipe · error
skill name must be lowercase letters, digits, and single hyp
Error message
skill name must be lowercase letters, digits, and single hyphens (max 64)
What it means
`parse_frontmatter` validates the skill `name` from SKILL.md frontmatter. The name must be non-empty, at most 64 bytes, not start or end with '-', contain no consecutive '--', and consist only of ASCII lowercase letters, digits, and single hyphens. Any violation raises this error. This normalization keeps skill names URL/ID-safe and consistent across the team skill registry.
Source
Thrown at crates/screenpipe-engine/src/cli/team_skills.rs:375
.ok_or_else(|| anyhow::anyhow!("SKILL.md needs a name"))?
.to_string();
let description = metadata
.get("description")
.and_then(serde_yaml::Value::as_str)
.map(str::trim)
.filter(|value| !value.is_empty())
.ok_or_else(|| anyhow::anyhow!("SKILL.md needs a description"))?
.to_string();
let valid_name = !name.is_empty()
&& name.len() <= 64
&& !name.starts_with('-')
&& !name.ends_with('-')
&& !name.contains("--")
&& name
.chars()
.all(|ch| ch.is_ascii_lowercase() || ch.is_ascii_digit() || ch == '-');
if !valid_name {
anyhow::bail!("skill name must be lowercase letters, digits, and single hyphens (max 64)");
}
if description.is_empty() || description.len() > 1024 {
anyhow::bail!("skill description must contain 1-1024 characters");
}
Ok((name, description))
}
fn print_preview(bundle: &PreparedBundle, title: Option<&str>) {
println!("team skill proposal preview");
println!("title: {}", title.unwrap_or(&bundle.name));
println!("name: {}", bundle.name);
println!("description: {}", bundle.description);
println!("source: {}", bundle.root.display());
println!(
"files: {} · bytes: {} · discovery: {} chars · activated: {} chars · scripts: {}",
bundle.files.len(),
bundle.total_bytes,
bundle.discovery_chars,View on GitHub (pinned to 4ebf712990)
Solutions
- Rewrite the name using only lowercase a-z, 0-9, and single hyphens (no leading/trailing '-', no '--'), max 64 chars
- Replace spaces or underscores with single hyphens (e.g. 'my_skill' -> 'my-skill')
- Convert uppercase letters to lowercase (e.g. 'MySkill' -> 'myskill')
- Shorten names over 64 characters; keep the long title in the description or preview title instead
Example fix
// before (SKILL.md frontmatter) name: My Great_Skill--v2 // after name: my-great-skill-v2
Defensive patterns
Strategy: validation
Validate before calling
fn is_valid_skill_name(name: &str) -> bool {
!name.is_empty()
&& name.len() <= 64
&& !name.starts_with('-')
&& !name.ends_with('-')
&& !name.contains("--")
&& name.chars().all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '-')
}
assert!(is_valid_skill_name(&name), "invalid skill name"); Type guard
fn valid_skill_name(name: &str) -> Option<&str> {
if !name.is_empty()
&& name.len() <= 64
&& !name.starts_with('-')
&& !name.ends_with('-')
&& !name.contains("--")
&& name.chars().all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '-')
{ Some(name) } else { None }
} Try / catch
match prepare_bundle(&skill_dir) {
Err(e) if e.to_string().contains("skill name must be") => {
eprintln!("use lowercase a-z, 0-9, single hyphens; max 64 chars: {e}");
}
other => other?,
} Prevention
- Derive names from folder names and slugify: lowercase, spaces/underscores to single hyphens
- Never use display titles verbatim as the name field
- Add a name-format lint/regex check (^[a-z0-9]+(-[a-z0-9]+)*$) in CI
- Keep names short; put longer descriptions in the description field (1-1024 chars)
When it happens
Trigger: Running the team skill bundle flow with a SKILL.md whose `name:` field uses uppercase letters, spaces, underscores, non-ASCII characters, leading/trailing hyphens, double hyphens, or exceeds 64 characters.
Common situations: Naming a skill with CamelCase or spaces (e.g. 'My Skill', 'my_skill'); copying a display title into the name field; migrating older skills that allowed other formats; auto-generated names from paths that contain uppercase or underscores; very long names from concatenated titles.
Related errors
- SKILL.md frontmatter closing fence must be on its own line
- SKILL.md needs YAML frontmatter
- Gemini API request failed: ${response.status} ${error}
- Gemini API streaming request failed: ${response.status} ${er
- skill description must contain 1-1024 characters
AI-assisted analysis of screenpipe/screenpipe@4ebf712990 (2026-09-01).
Data as JSON: /api/errors/9eaafd6a2874c53e.
Report an issue: GitHub.