{"record":{"id":"c3ddd2018c2358c1","repo":"mastra-ai/mastra","slug":"scorer-definition-with-id-id-already-exists","errorCode":null,"errorMessage":"Scorer definition with id ${id} already exists","messagePattern":"Scorer definition with id (.+?) already exists","errorType":"http","errorClass":"HTTPException","httpStatus":409,"severity":"warning","filePath":"packages/server/src/server/handlers/stored-scorers.ts","lineNumber":173,"sourceCode":"\n      const scorerStore = await storage.getStore('scorerDefinitions');\n      if (!scorerStore) {\n        throw new HTTPException(500, { message: 'Scorer definitions storage domain is not available' });\n      }\n\n      // Derive ID from name if not explicitly provided\n      const id = providedId || toSlug(name);\n\n      if (!id) {\n        throw new HTTPException(400, {\n          message: 'Could not derive scorer definition ID from name. Please provide an explicit id.',\n        });\n      }\n\n      // Check if scorer definition with this ID already exists\n      const existing = await scorerStore.getById(id);\n      if (existing) {\n        throw new HTTPException(409, { message: `Scorer definition with id ${id} already exists` });\n      }\n\n      await scorerStore.create({\n        scorerDefinition: {\n          id,\n          authorId,\n          metadata: scopeStoredResourceMetadata(metadata, await getStoredResourceScope(mastra, requestContext)),\n          name,\n          description,\n          type,\n          model,\n          instructions,\n          scoreRange,\n          presetConfig,\n          defaultSampling,\n        },\n      });\n","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/handlers/stored-scorers.ts#L155-L191","documentation":"Thrown by the create handler when `scorerStore.getById(id)` finds an existing scorer definition with the same derived or provided id. Creation would violate the id uniqueness constraint, so the handler responds with HTTP 409 Conflict instead of overwriting.","triggerScenarios":"POST create with an `id` (explicit or slugified from `name`) that already has a stored scorer definition in the current storage backend — e.g. re-running an idempotent-looking seed script, or a name that slugs to an existing scorer's id.","commonSituations":"Double-submitting a create form; replaying setup scripts in CI against persistent storage; names like 'quality' colliding with an existing 'quality' scorer; re-creating a scorer deleted only at a different `status`.","solutions":["Choose a unique id (or rename so the slug differs) before creating.","Use the update endpoint for the existing id instead of create if you intend to modify it.","Catch the 409 client-side and fall back to a fetch/update flow.","Delete the existing scorer first if it should be replaced."],"exampleFix":"// before\ncreateScorer({ id: 'quality', name: 'Quality' }); // 409 if 'quality' exists\n\n// after\ntry {\n  await createScorer({ id: 'quality', name: 'Quality' });\n} catch (e) {\n  if (e.status === 409) await updateScorer('quality', { name: 'Quality' });\n  else throw e;\n}","handlingStrategy":"try-catch","validationCode":"const existing = await getStoredScorer(id).catch(() => null);\nif (existing) throw new Error(`Scorer '${id}' already exists — use update instead of create.`);","typeGuard":null,"tryCatchPattern":"try {\n  await createScorer(payload);\n} catch (e) {\n  if (e.status === 409) {\n    return updateScorer(payload.id, payload); // upsert-style fallback\n  }\n  throw e;\n}","preventionTips":["Implement upsert semantics (catch 409 → update) in client wrappers","Make seed/CI scripts check existence before create","Prefix ids per environment (dev-, ci-) to avoid collisions in shared storage"],"tags":["http-409","conflict","duplicate","rest-api"],"backgroundTag":"duplicate-resource-conflict","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}