mastra-ai/mastra · warning · HTTPException

Scorer definition with id ${id} already exists

Error message

Scorer definition with id ${id} already exists

What it means

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.

Source

Thrown at packages/server/src/server/handlers/stored-scorers.ts:173

      const scorerStore = await storage.getStore('scorerDefinitions');
      if (!scorerStore) {
        throw new HTTPException(500, { message: 'Scorer definitions storage domain is not available' });
      }

      // Derive ID from name if not explicitly provided
      const id = providedId || toSlug(name);

      if (!id) {
        throw new HTTPException(400, {
          message: 'Could not derive scorer definition ID from name. Please provide an explicit id.',
        });
      }

      // Check if scorer definition with this ID already exists
      const existing = await scorerStore.getById(id);
      if (existing) {
        throw new HTTPException(409, { message: `Scorer definition with id ${id} already exists` });
      }

      await scorerStore.create({
        scorerDefinition: {
          id,
          authorId,
          metadata: scopeStoredResourceMetadata(metadata, await getStoredResourceScope(mastra, requestContext)),
          name,
          description,
          type,
          model,
          instructions,
          scoreRange,
          presetConfig,
          defaultSampling,
        },
      });

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Choose a unique id (or rename so the slug differs) before creating.
  2. Use the update endpoint for the existing id instead of create if you intend to modify it.
  3. Catch the 409 client-side and fall back to a fetch/update flow.
  4. Delete the existing scorer first if it should be replaced.

Example fix

// before
createScorer({ id: 'quality', name: 'Quality' }); // 409 if 'quality' exists

// after
try {
  await createScorer({ id: 'quality', name: 'Quality' });
} catch (e) {
  if (e.status === 409) await updateScorer('quality', { name: 'Quality' });
  else throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

const existing = await getStoredScorer(id).catch(() => null);
if (existing) throw new Error(`Scorer '${id}' already exists — use update instead of create.`);

Try / catch

try {
  await createScorer(payload);
} catch (e) {
  if (e.status === 409) {
    return updateScorer(payload.id, payload); // upsert-style fallback
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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`.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/c3ddd2018c2358c1. Report an issue: GitHub.