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
- 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.
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
- 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
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
- Skill with id ${id} already exists
- Agent with id ${id} already exists
- MCP client with id ${id} already exists
- Workspace with id ${id} already exists
- Skipped: Scorer ${filename} already exists at ${scorersPath}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/c3ddd2018c2358c1.
Report an issue: GitHub.