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

  1. Sanitize the skill name to match /^[A-Za-z0-9._-]+$/ before calling writeSkills (strip/replace invalid characters).
  2. Do not derive names directly from file paths — use path.basename and validate the result.
  3. Reject or skip skills with invalid names upstream, surfacing a friendly error to users.
  4. 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

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


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/18f3bcace8b28a25. Report an issue: GitHub.