{"record":{"id":"7f41a8494e1970d5","repo":"mastra-ai/mastra","slug":"invalid-skill-name-validation-errors-join","errorCode":null,"errorMessage":"Invalid skill \"${name}\": ${validation.errors.join('; ')}","messagePattern":"Invalid skill \"(.+?)\": (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/skills/create-skill.ts","lineNumber":49,"sourceCode":" * Create an inline skill from code — no filesystem needed.\n *\n * The returned object implements the `Skill` interface and can be passed\n * directly to an Agent's `skills` config or used anywhere a `Skill` is expected.\n *\n * @throws Error if the skill metadata fails validation\n */\nexport function createSkill(input: InlineSkillInput): InlineSkill {\n  const { name, description, instructions, license, compatibility, metadata, references } = input;\n\n  // Validate metadata (same checks as filesystem-discovered skills)\n  const validation = validateSkillMetadata(\n    { name, description, license, compatibility, 'user-invocable': input['user-invocable'], metadata },\n    undefined,\n    instructions,\n  );\n\n  if (!validation.valid) {\n    throw new Error(`Invalid skill \"${name}\": ${validation.errors.join('; ')}`);\n  }\n\n  const referenceKeys = references ? Object.keys(references) : [];\n\n  return {\n    __inline: true as const,\n    __referenceContents: references ?? {},\n    name,\n    description,\n    instructions,\n    license,\n    compatibility,\n    'user-invocable': input['user-invocable'],\n    metadata,\n    // Inline skills use a synthetic path: `inline/<name>`\n    path: `inline/${name}`,\n    source: { type: 'local', projectPath: `inline/${name}` },\n    references: referenceKeys,","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/skills/create-skill.ts#L31-L67","documentation":"createSkill() validates the assembled skill definition (frontmatter fields like name, description, license, compatibility, user-invocable, metadata, plus instructions) before returning the inline skill object. When validation reports any errors, createSkill throws with all error messages joined by semicolons. This surfaces schema/shape problems with the skill definition at creation time.","triggerScenarios":"Calling createSkill() (directly or via helpers like skill/skill1/skill2/ws/agentSkills/workspaceSkills) with input that fails validation — e.g. missing or malformed 'description', invalid 'compatibility' value, or bad metadata shape — such that validation.valid === false.","commonSituations":"Porting an existing SKILL.md frontmatter that omits required fields; hand-building skills in code with typos in field names (e.g. 'compatable'); programmatically generated metadata containing wrong types (array where object expected); older skill format not matching the current schema.","solutions":["Read the joined error list in the message and fix each named field in the input to createSkill.","Ensure required frontmatter fields (name, description) are non-empty strings and compatibility/user-invocable/metadata match the documented schema.","If migrating from a file-based skill, parse SKILL.md frontmatter through the same validation path to find which fields are rejected.","Check field-name spelling against the current skill schema (APIs may have changed across versions)."],"exampleFix":"// before\ncreateSkill({\n  name: 'my-skill',\n  compatable: 'claude', // typo'd field, description missing\n  instructions: 'Do things',\n});\n// after\ncreateSkill({\n  name: 'my-skill',\n  description: 'Does useful things',\n  compatibility: 'claude',\n  instructions: 'Do things',\n});","handlingStrategy":"validation","validationCode":"function assertValidSkillInput(input) {\n  const errors = [];\n  if (!input || typeof input !== 'object') errors.push('input must be an object');\n  if (typeof input?.name !== 'string' || !input.name.trim()) errors.push('name is required');\n  if (typeof input?.description !== 'string' || !input.description.trim()) errors.push('description is required');\n  if (input?.metadata && typeof input.metadata !== 'object') errors.push('metadata must be an object');\n  if (errors.length) throw new TypeError(`Invalid skill input: ${errors.join('; ')}`);\n}","typeGuard":"function isSkillInput(x) {\n  return typeof x === 'object' && x !== null &&\n    typeof x.name === 'string' && x.name.length > 0 &&\n    typeof x.description === 'string' && x.description.length > 0 &&\n    typeof x.instructions === 'string';\n}","tryCatchPattern":"try {\n  const skill = createSkill(input);\n} catch (e) {\n  if (String(e?.message).startsWith('Invalid skill')) {\n    // message lists each validation error joined by '; '\n    console.error('Skill validation failed:', e.message);\n    // fix fields per message, or surface to the user\n  } else throw e;\n}","preventionTips":["Validate frontmatter fields (name, description, compatibility, metadata) against the documented schema before calling createSkill.","If migrating file-based skills, run the same validation on parsed SKILL.md frontmatter first.","Keep field names exactly as documented — typos silently become invalid inputs.","Write a fixture test that creates each of your skills at CI time to catch schema drift."],"tags":["skills","validation","schema"],"backgroundTag":"schema-validation-failed","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}