vercel/ai · error · Error
Invalid skill name: ${name}
Error message
Invalid skill name: ${name} What it means
Thrown by validateSkillName in packages/harness/src/utils/write-skills.ts when a skill name fails the configured name pattern (default /^[A-Za-z0-9._-]+$/) or is '.' or '..'. Skill names become directory names inside the sandbox, so unsafe characters (slashes, spaces, shell metacharacters) are rejected to prevent path traversal and injection. A custom `invalidSkillNameMessage` can override the default message.
Source
Thrown at packages/harness/src/utils/write-skills.ts:482
const matches = SAFE_MANIFEST_SKILL_NAME.test(name);
SAFE_MANIFEST_SKILL_NAME.lastIndex = 0;
return matches && name !== '.' && name !== '..' && !name.includes('/');
}
function validateSkillName({
name,
pattern,
message,
}: {
name: string;
pattern: RegExp;
message?: (input: { name: string }) => string;
}): string {
pattern.lastIndex = 0;
const matches = pattern.test(name);
pattern.lastIndex = 0;
if (!matches || name === '.' || name === '..') {
throw new Error(message?.({ name }) ?? `Invalid skill name: ${name}`);
}
return name;
}
function normalizeSkillFilePath({
skillName,
filePath,
mode,
message,
}: {
skillName?: string;
filePath: string;
mode: SkillFilePathMode;
message?: (input: { skillName: string; filePath: string }) => string;
}): string {
const normalized =
mode === 'strip-leading-slashes'
? filePath.replace(/^\/+/, '')View on GitHub (pinned to 69428b1f8b)
Solutions
- Sanitize the skill name to match /^[A-Za-z0-9._-]+$/ before calling writeSkills (strip/replace invalid characters).
- Do not derive names directly from file paths — use path.basename and validate the result.
- Reject or skip skills with invalid names upstream, surfacing a friendly error to users.
- If you need a different naming scheme, pass a custom skillNamePattern/invalidSkillNameMessage, keeping names path-safe.
Example fix
// before
await writeSkills({ sandbox, rootDir, skills: [{ name: 'my skill/docs', files }] }); // throws Invalid skill name
// after
const safeName = name.replace(/[^A-Za-z0-9._-]/g, '-');
await writeSkills({ sandbox, rootDir, skills: [{ name: safeName, files }] }); Defensive patterns
Strategy: validation
Validate before calling
const SAFE = /^[A-Za-z0-9._-]+$/;
function assertSafeSkillName(name: string): void {
if (!SAFE.test(name) || name === '.' || name === '..') {
throw new Error(`Skill name must match ${SAFE} and not be '.'/'..': ${name}`);
}
}
skills.forEach(s => assertSafeSkillName(s.name)); Type guard
function isSafeSkillName(name: string): boolean {
return /^[A-Za-z0-9._-]+$/.test(name) && name !== '.' && name !== '..';
} Try / catch
try {
await writeSkills({ sandbox, rootDir, skills });
} catch (error) {
if (/Invalid skill name:/.test((error as Error).message)) {
const sanitized = skills.map(s => ({ ...s, name: s.name.replace(/[^A-Za-z0-9._-]/g, '-') }));
await writeSkills({ sandbox, rootDir, skills: sanitized });
} else throw error;
} Prevention
- Sanitize names at ingestion: replace everything outside [A-Za-z0-9._-] with '-'.
- Never derive skill names from raw file paths or untrusted user input.
- Reject '.' and '..' and any name containing '/' or shell metacharacters.
- Validate names in a shared helper so every writeSkills call site is covered.
When it happens
Trigger: Calling writeSkills (or code reaching validateSkillName) with a skill whose name contains characters outside [A-Za-z0-9._-], equals '.' or '..', or violates a custom `skillNamePattern` supplied in WriteSkillsOptions.
Common situations: Skill names derived from user input or file names containing spaces, unicode, or slashes; names like '.'/'..' from path parsing; localized names with accents; names built by joining path segments instead of taking the basename.
Related errors
- Duplicate skill name: ${skills[index]!.name}
- 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.
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/18f3bcace8b28a25.
Report an issue: GitHub.