vercel/ai · error · Error
Invalid Cline skill name: ${skill.name}
Error message
Invalid Cline skill name: ${skill.name} What it means
projectClineSkills validates each skill's name against CLINE_SKILL_NAME_PATTERN and additionally rejects '.' and '..'. Names failing the pattern (which disallow path-hostile or malformed identifiers) throw this plain Error before any duplicate check. Cline maps skill names to directories, so unsafe names would escape or break the skills layout.
Source
Thrown at packages/harness-cline/src/cline-skills.ts:96
return { signature, tool };
}
function projectClineSkills({
skills,
}: {
skills: ReadonlyArray<HarnessV1Skill>;
}): ReadonlyArray<ProjectedClineSkill> {
const names = new Set<string>();
const ids = new Set<string>();
return skills
.map(skill => {
if (
!CLINE_SKILL_NAME_PATTERN.test(skill.name) ||
skill.name === '.' ||
skill.name === '..'
) {
throw new Error(`Invalid Cline skill name: ${skill.name}`);
}
if (names.has(skill.name)) {
throw new Error(`Duplicate Cline skill name: ${skill.name}`);
}
names.add(skill.name);
const id = normalizeSkillToken(skill.name);
if (ids.has(id)) {
throw new Error(`Duplicate Cline skill identifier: ${id}`);
}
ids.add(id);
return {
id,
name: skill.name,
description: skill.description,
content: skill.content,
files: (skill.files ?? [])View on GitHub (pinned to 69428b1f8b)
Solutions
- Rename the offending skill so its name matches CLINE_SKILL_NAME_PATTERN (kebab-case-ish, no separators, not '.' or '..').
- Sanitize names at load time: derive the name from the filename, trim, replace invalid characters with '-', and skip entries like '.'/'..'.
- Add a preflight filter in your skill loader that mirrors the harness regex so invalid skills are rejected early with a clearer message.
Example fix
// before
prompt({ skills: [{ name: '../hostile', ... }] });
// after
const safeName = rawName.replace(/[^a-zA-Z0-9_-]/g, '-').replace(/^-+|-+$/g, '');
prompt({ skills: [{ name: safeName || 'skill', ... }] }); Defensive patterns
Strategy: validation
Validate before calling
const CLINE_SKILL_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]*$/; // mirror harness pattern
function assertValidSkillName(name: string) {
if (!CLINE_SKILL_NAME_PATTERN.test(name) || name === '.' || name === '..') {
throw new Error(`Invalid skill name: ${name}`);
}
}
skills.forEach(s => assertValidSkillName(s.name)); Try / catch
try {
await session.prompt({ text, skills });
} catch (e) {
if (e instanceof Error && e.message.startsWith('Invalid Cline skill name')) {
const bad = e.message.split(': ')[1];
skills = skills.filter(s => s.name !== bad);
await session.prompt({ text, skills });
} else throw e;
} Prevention
- Normalize skill names to kebab-case when loading from disk; never use raw directory names.
- Skip '.', '..' and hidden entries when enumerating skill folders.
- Run the harness name regex against every skill in your skill loader's unit tests.
When it happens
Trigger: Passing a skill in turnOpts.skills whose name is empty, contains characters outside the allowed pattern (e.g. spaces, slashes, 'my skill/', '../escape'), or is exactly '.' or '..'.
Common situations: Generating skill names from user input or file paths without normalization; loading skills from a directory and using raw folder names including spaces or unicode; hand-written skill definitions with typos or separators in the name.
Related errors
- maxEmbeddingsPerCall must be greater than 0
- maxInputBytesPerCall must be greater than 0
- No image generated.
- No object generated: the model did not return a response.
- ACP harnessId must be a stable kebab-case identifier; receiv
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/dffc2a5b8bfda6cd.
Report an issue: GitHub.