{"record":{"id":"18f3bcace8b28a25","repo":"vercel/ai","slug":"invalid-skill-name-name","errorCode":null,"errorMessage":"Invalid skill name: ${name}","messagePattern":"Invalid skill name: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/harness/src/utils/write-skills.ts","lineNumber":482,"sourceCode":"  const matches = SAFE_MANIFEST_SKILL_NAME.test(name);\n  SAFE_MANIFEST_SKILL_NAME.lastIndex = 0;\n  return matches && name !== '.' && name !== '..' && !name.includes('/');\n}\n\nfunction validateSkillName({\n  name,\n  pattern,\n  message,\n}: {\n  name: string;\n  pattern: RegExp;\n  message?: (input: { name: string }) => string;\n}): string {\n  pattern.lastIndex = 0;\n  const matches = pattern.test(name);\n  pattern.lastIndex = 0;\n  if (!matches || name === '.' || name === '..') {\n    throw new Error(message?.({ name }) ?? `Invalid skill name: ${name}`);\n  }\n  return name;\n}\n\nfunction normalizeSkillFilePath({\n  skillName,\n  filePath,\n  mode,\n  message,\n}: {\n  skillName?: string;\n  filePath: string;\n  mode: SkillFilePathMode;\n  message?: (input: { skillName: string; filePath: string }) => string;\n}): string {\n  const normalized =\n    mode === 'strip-leading-slashes'\n      ? filePath.replace(/^\\/+/, '')","sourceCodeStart":464,"sourceCodeEnd":500,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/harness/src/utils/write-skills.ts#L464-L500","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait writeSkills({ sandbox, rootDir, skills: [{ name: 'my skill/docs', files }] }); // throws Invalid skill name\n// after\nconst safeName = name.replace(/[^A-Za-z0-9._-]/g, '-');\nawait writeSkills({ sandbox, rootDir, skills: [{ name: safeName, files }] });","handlingStrategy":"validation","validationCode":"const SAFE = /^[A-Za-z0-9._-]+$/;\nfunction assertSafeSkillName(name: string): void {\n  if (!SAFE.test(name) || name === '.' || name === '..') {\n    throw new Error(`Skill name must match ${SAFE} and not be '.'/'..': ${name}`);\n  }\n}\nskills.forEach(s => assertSafeSkillName(s.name));","typeGuard":"function isSafeSkillName(name: string): boolean {\n  return /^[A-Za-z0-9._-]+$/.test(name) && name !== '.' && name !== '..';\n}","tryCatchPattern":"try {\n  await writeSkills({ sandbox, rootDir, skills });\n} catch (error) {\n  if (/Invalid skill name:/.test((error as Error).message)) {\n    const sanitized = skills.map(s => ({ ...s, name: s.name.replace(/[^A-Za-z0-9._-]/g, '-') }));\n    await writeSkills({ sandbox, rootDir, skills: sanitized });\n  } else throw error;\n}","preventionTips":["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."],"tags":["validation","skills","harness","path-safety","security"],"backgroundTag":"invalid-name-validation","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}