vercel/ai · error · Error
Duplicate Cline skill identifier: ${id}
Error message
Duplicate Cline skill identifier: ${id} What it means
After validating unique skill names, projectClineSkills derives a normalized identifier via normalizeSkillToken(skill.name) and requires ids to be unique too. Two distinct names can normalize to the same token (e.g. 'My Skill' and 'my-skill'), which would create ambiguous skill ids, so it throws.
Source
Thrown at packages/harness-cline/src/cline-skills.ts:105
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 ?? [])
.map(file => ({
path: normalizeSkillFilePath({
skillName: skill.name,
filePath: file.path,
}),
content: file.content,
}))
.sort(
(left, right) =>View on GitHub (pinned to 69428b1f8b)
Solutions
- Rename one skill so its normalized token differs (change casing, spacing, or punctuation).
- Check the colliding id printed in the message and inspect which names map to it.
- Pre-normalize skill names (kebab-case) across all skill sources before registering them.
Example fix
// before skills named 'Code Review' and 'code-review' both registered // after // rename one, e.g. 'Code Review' -> 'code-review-strict'
Defensive patterns
Strategy: validation
Validate before calling
const ids = new Set();
for (const s of skills) {
const id = s.name.toLowerCase().replace(/[^a-z0-9]+/g, '-');
if (ids.has(id)) throw new Error(`colliding skill id: ${id}`);
ids.add(id);
} Try / catch
try {
await projectedSkills(input);
} catch (e) {
if (/Duplicate Cline skill identifier/.test(String(e?.message))) {
// rename skill to avoid token collision, then retry
} else throw e;
} Prevention
- Author all skill names in kebab-case so name and id match
- Pre-normalize names with the same rule the harness uses
- Avoid names differing only by casing, spaces, or underscores
When it happens
Trigger: projectClineSkills receives skills with distinct names that normalize to the same token, e.g. 'Deploy Helper' and 'deploy-helper' or 'deploy_helper' and 'deploy-helper'.
Common situations: Skills authored in different naming conventions (Title Case vs kebab-case) that collide after token normalization; importing the same skill from two sources under slightly different names.
Related errors
- Duplicate Cline skill name: ${skill.name}
- Invalid Cline skill file path for ${skillName}: ${filePath}
- maxEmbeddingsPerCall must be greater than 0
- maxInputBytesPerCall must be greater than 0
- No image generated.
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/8779d5e66716fb4c.
Report an issue: GitHub.