{"record":{"id":"da9631e11a635a49","repo":"mastra-ai/mastra","slug":"version-number-input-versionnumber-already-exis","errorCode":null,"errorMessage":"Version number ${input.versionNumber} already exists for agent ${input.agentId}","messagePattern":"Version number (.+?) already exists for agent (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/storage/domains/agents/inmemory.ts","lineNumber":230,"sourceCode":"      perPage: perPageForResponse,\n      hasMore: offset + perPage < clonedAgents.length,\n    };\n  }\n\n  // ==========================================================================\n  // Agent Version Methods\n  // ==========================================================================\n\n  async createVersion(input: CreateVersionInput): Promise<AgentVersion> {\n    // Check if version with this ID already exists (versions are immutable)\n    if (this.db.agentVersions.has(input.id)) {\n      throw new Error(`Version with id ${input.id} already exists`);\n    }\n\n    // Check for duplicate (agentId, versionNumber) pair\n    for (const version of this.db.agentVersions.values()) {\n      if (version.agentId === input.agentId && version.versionNumber === input.versionNumber) {\n        throw new Error(`Version number ${input.versionNumber} already exists for agent ${input.agentId}`);\n      }\n    }\n\n    const version: AgentVersion = {\n      ...input,\n      createdAt: new Date(),\n    };\n\n    // Deep clone before storing to prevent external mutation\n    this.db.agentVersions.set(input.id, this.deepCopyVersion(version));\n    return this.deepCopyVersion(version);\n  }\n\n  async getVersion(id: string): Promise<AgentVersion | null> {\n    const version = this.db.agentVersions.get(id);\n    return version ? this.deepCopyVersion(version) : null;\n  }\n","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/storage/domains/agents/inmemory.ts#L212-L248","documentation":"`createVersion` enforces uniqueness of the (agentId, versionNumber) pair: if any stored version for the same agent already has that versionNumber, the call throws. Version numbers per agent must be strictly new.","triggerScenarios":"Calling `createVersion` with `{ agentId, versionNumber }` that already exists — e.g. re-publishing version 1 of an agent, or concurrent publishes that both computed the next number.","commonSituations":"Off-by-one in computing `versionNumber` (reusing an existing number); running seed scripts twice; two requests racing to publish the same next version without locking.","solutions":["Query existing versions for the agent and compute versionNumber as max(existing)+1 before creating","If re-publishing is intended, increment to a fresh versionNumber instead of reusing one","Catch the error and reconcile by fetching the existing version in concurrent flows"],"exampleFix":"// before\nawait agents.createVersion({ id, agentId, versionNumber: 1, ... });\n// after\nconst { versions } = await agents.listVersions({ agentId, perPage: false });\nconst next = versions.reduce((m, v) => Math.max(m, v.versionNumber), 0) + 1;\nawait agents.createVersion({ id, agentId, versionNumber: next, ... });","handlingStrategy":"validation","validationCode":"const { versions } = await agentsDomain.listVersions({ agentId, perPage: false });\nif (versions.some(v => v.versionNumber === versionNumber)) {\n  throw new Error(`versionNumber ${versionNumber} already published for ${agentId}`);\n}","typeGuard":"null","tryCatchPattern":"try {\n  return await agentsDomain.createVersion({ id, agentId, versionNumber, ... });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('already exists for agent')) {\n    const { versions } = await agentsDomain.listVersions({ agentId, perPage: false });\n    const next = versions.reduce((m, v) => Math.max(m, v.versionNumber), 0) + 1;\n    return agentsDomain.createVersion({ id, agentId, versionNumber: next, ... });\n  }\n  throw e;\n}","preventionTips":["Compute the next versionNumber as max(existing) + 1 before publishing","Guard concurrent publishes with a lock or catch-and-reconcile","Double-check off-by-one logic when deriving version numbers","Never re-publish an existing (agentId, versionNumber) pair — increment instead"],"tags":["storage","duplicate","versioning"],"backgroundTag":"duplicate-resource-conflict","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}