{"record":{"id":"e9e6293638b1826b","repo":"mastra-ai/mastra","slug":"version-with-id-input-id-already-exists-e9e629","errorCode":null,"errorMessage":"Version with id ${input.id} already exists","messagePattern":"Version with id (.+?) already exists","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/storage/domains/scorer-definitions/inmemory.ts","lineNumber":208,"sourceCode":"    const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n    return {\n      scorerDefinitions: clonedScorers.slice(offset, offset + perPage),\n      total: clonedScorers.length,\n      page,\n      perPage: perPageForResponse,\n      hasMore: offset + perPage < clonedScorers.length,\n    };\n  }\n\n  // ==========================================================================\n  // Scorer Definition Version Methods\n  // ==========================================================================\n\n  async createVersion(input: CreateScorerDefinitionVersionInput): Promise<ScorerDefinitionVersion> {\n    // Check if version with this ID already exists\n    if (this.db.scorerDefinitionVersions.has(input.id)) {\n      throw new Error(`Version with id ${input.id} already exists`);\n    }\n\n    // Check for duplicate (scorerDefinitionId, versionNumber) pair\n    for (const version of this.db.scorerDefinitionVersions.values()) {\n      if (version.scorerDefinitionId === input.scorerDefinitionId && version.versionNumber === input.versionNumber) {\n        throw new Error(\n          `Version number ${input.versionNumber} already exists for scorer definition ${input.scorerDefinitionId}`,\n        );\n      }\n    }\n\n    const version: ScorerDefinitionVersion = {\n      ...input,\n      createdAt: new Date(),\n    };\n\n    // Deep clone before storing\n    this.db.scorerDefinitionVersions.set(input.id, this.deepCopyVersion(version));","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/storage/domains/scorer-definitions/inmemory.ts#L190-L226","documentation":"The in-memory scorer-definitions storage createVersion() throws when a version with the same id is already stored in scorerDefinitionVersions. A second check rejects duplicate (scorerDefinitionId, versionNumber) pairs right after. Both keys must be unique for version history to be addressable.","triggerScenarios":"Calling createVersion({ id: 'v1', scorerDefinitionId: 's1', versionNumber: 1, ... }) twice with the same id; re-running seedAgent/create flows that already inserted the version; retrying after a partial success.","commonSituations":"Re-deploying or re-importing scorer versions with fixed ids; retries without idempotency keys; concurrent writers both computing 'next version' from the same snapshot.","solutions":["Generate a fresh unique version id (crypto.randomUUID()) for each createVersion call.","Compute versionNumber as max(existing versions for the definition)+1 rather than a constant.","Catch the error and treat it as 'already created' for idempotent replay flows.","Serialize version creation (or retry on conflict by re-reading current versions) if multiple writers create versions concurrently."],"exampleFix":"// before\nawait storage.scorerDefinitions.createVersion({ id: 'helpfulness-v1', scorerDefinitionId, versionNumber: 1, config });\n// after\nconst id = crypto.randomUUID();\nconst existing = await storage.scorerDefinitions.listVersions(scorerDefinitionId);\nconst versionNumber = existing.versions.reduce((m, v) => Math.max(m, v.versionNumber), 0) + 1;\nawait storage.scorerDefinitions.createVersion({ id, scorerDefinitionId, versionNumber, config });","handlingStrategy":"validation","validationCode":"const { versions } = await storage.scorerDefinitions.listVersions(scorerDefinitionId);\nconst nextNumber = versions.reduce((m, v) => Math.max(m, v.versionNumber), 0) + 1;\nif (versions.some(v => v.id === versionId)) {\n  throw new Error(`version id ${versionId} already used`);\n}","typeGuard":"function versionIdIsFree(versions: { id: string }[], id: string): boolean {\n  return !versions.some(v => v.id === id);\n}","tryCatchPattern":"try {\n  await storage.scorerDefinitions.createVersion(input);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('already exists')) {\n    return; // treat as idempotent success on replay\n  }\n  throw e;\n}","preventionTips":["Use crypto.randomUUID() for every version id.","Compute versionNumber as max+1 from current stored versions, not a constant.","Make retries idempotent: same input should be safely skippable when the error says 'already exists'.","Serialize concurrent version creation per scorer definition to avoid races."],"tags":["storage","duplicate-key","scorer-definitions","in-memory"],"backgroundTag":"duplicate-version-id","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}