{"record":{"id":"da49535f9ab5e426","repo":"mastra-ai/mastra","slug":"skill-with-id-skill-id-already-exists","errorCode":null,"errorMessage":"Skill with id ${skill.id} already exists","messagePattern":"Skill with id (.+?) already exists","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/storage/domains/skills/inmemory.ts","lineNumber":51,"sourceCode":"  async dangerouslyClearAll(): Promise<void> {\n    this.db.skills.clear();\n    this.db.skillVersions.clear();\n  }\n\n  // ==========================================================================\n  // Skill CRUD Methods\n  // ==========================================================================\n\n  async getById(id: string): Promise<StorageSkillType | null> {\n    const config = this.db.skills.get(id);\n    return config ? this.deepCopyConfig(config) : null;\n  }\n\n  async create(input: { skill: StorageCreateSkillInput }): Promise<StorageSkillType> {\n    const { skill } = input;\n\n    if (this.db.skills.has(skill.id)) {\n      throw new Error(`Skill with id ${skill.id} already exists`);\n    }\n\n    const now = new Date();\n    const visibility = skill.visibility ?? (skill.authorId ? 'private' : undefined);\n    const newConfig: StorageSkillType = {\n      id: skill.id,\n      status: 'draft',\n      activeVersionId: undefined,\n      authorId: skill.authorId,\n      visibility,\n      favoriteCount: 0,\n      createdAt: now,\n      updatedAt: now,\n    };\n\n    this.db.skills.set(skill.id, newConfig);\n\n    // Extract config fields from the flat input (everything except record fields)","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/storage/domains/skills/inmemory.ts#L33-L69","documentation":"The in-memory skills storage create() checks its skills map and rejects creation when a skill with the same id already exists. Ids are primary keys, so create is insert-only and duplicates are an error, not an overwrite.","triggerScenarios":"Calling create({ skill: { id: 'x', ... } }) twice for the same id, or via seedSkill re-running against an already-seeded store; re-running a seed/demo script on a warm process.","commonSituations":"Non-idempotent seed functions run on app startup; test setup reusing the same in-memory DB across cases; retrying a request after a timeout when the first attempt actually succeeded.","solutions":["Check existence first with this.db.skills.has(id) equivalent / a get call, then create or update accordingly.","Make seeds idempotent: skip or update when the id already exists instead of always creating.","Use unique ids per run (suffix with timestamp/uuid) when duplicates are expected.","Clear the store between test runs."],"exampleFix":"// before\nawait skillsStorage.create({ skill: { id: 'deploy', ...cfg } }); // throws on 2nd run\n// after\nconst existing = await skillsStorage.get({ id: 'deploy' });\nif (!existing) await skillsStorage.create({ skill: { id: 'deploy', ...cfg } });\nelse await skillsStorage.update({ id: 'deploy', ...cfg });","handlingStrategy":"validation","validationCode":"const existing = await storage.get({ id: skill.id });\nif (existing) throw new Error(`skill ${skill.id} already exists`);","typeGuard":"async function canCreate(storage: InMemorySkillsStorage, id: string): Promise<boolean> {\n  return !(await storage.get({ id }));\n}","tryCatchPattern":"try {\n  return await storage.create({ skill });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('already exists')) {\n    return storage.update({ ...skill });\n  }\n  throw e;\n}","preventionTips":["Make seed functions idempotent (check-before-create or update-on-exists).","Generate unique ids (uuid/slug+timestamp) when creating user-driven skills.","Reset the in-memory store between test runs.","Treat create as insert-only; route re-creation attempts to update."],"tags":["storage","duplicate-key","skills","in-memory","idempotency"],"backgroundTag":"duplicate-key-conflict","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}