mastra-ai/mastra · error

Scorer definition with id ${scorerDefinition.id} already exi

Error message

Scorer definition with id ${scorerDefinition.id} already exists

What it means

The in-memory scorer-definitions storage create() throws when a scorer definition with the same id is already stored. Scorer definition ids are unique primary keys; the store rejects duplicates rather than overwriting so existing versions/status remain intact.

Source

Thrown at packages/core/src/storage/domains/scorer-definitions/inmemory.ts:49

  async dangerouslyClearAll(): Promise<void> {
    this.db.scorerDefinitions.clear();
    this.db.scorerDefinitionVersions.clear();
  }

  // ==========================================================================
  // Scorer Definition CRUD Methods
  // ==========================================================================

  async getById(id: string): Promise<StorageScorerDefinitionType | null> {
    const scorer = this.db.scorerDefinitions.get(id);
    return scorer ? this.deepCopyScorer(scorer) : null;
  }

  async create(input: { scorerDefinition: StorageCreateScorerDefinitionInput }): Promise<StorageScorerDefinitionType> {
    const { scorerDefinition } = input;

    if (this.db.scorerDefinitions.has(scorerDefinition.id)) {
      throw new Error(`Scorer definition with id ${scorerDefinition.id} already exists`);
    }

    const now = new Date();
    const newScorer: StorageScorerDefinitionType = {
      id: scorerDefinition.id,
      status: 'draft',
      activeVersionId: undefined,
      authorId: scorerDefinition.authorId,
      organizationId: scorerDefinition.organizationId,
      projectId: scorerDefinition.projectId,
      metadata: scorerDefinition.metadata,
      createdAt: now,
      updatedAt: now,
    };

    this.db.scorerDefinitions.set(scorerDefinition.id, newScorer);

    // Extract config fields from the flat input (everything except scorer-record fields)

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Generate unique ids (crypto.randomUUID()) for each new scorer definition.
  2. Check existence first (list/get) and skip creation if the id is present.
  3. Catch the error and treat it as idempotent success if the definition is unchanged.
  4. Use a fresh storage instance or clear the store between seed runs.

Example fix

// before
await storage.scorerDefinitions.create({ scorerDefinition: { id: 'helpfulness', ... } });
// after
const existing = await storage.scorerDefinitions.list();
if (!existing.scorers.some(s => s.id === 'helpfulness')) {
  await storage.scorerDefinitions.create({ scorerDefinition: { id: 'helpfulness', ... } });
}
Defensive patterns

Strategy: validation

Validate before calling

const { scorers } = await storage.scorerDefinitions.list({ perPage: false });
if (scorers.some(s => s.id === scorerDefinition.id)) {
  throw new Error(`scorer definition ${scorerDefinition.id} already exists`);
}

Type guard

function isUniqueScorerId(scorers: { id: string }[], id: string): boolean {
  return !scorers.some(s => s.id === id);
}

Try / catch

try {
  return await storage.scorerDefinitions.create({ scorerDefinition });
} catch (e) {
  if (e instanceof Error && e.message.includes('Scorer definition with id') && e.message.includes('already exists')) {
    return; // idempotent seed
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling storage.scorerDefinitions.create({ scorerDefinition: { id: 's1', ... } }) when 's1' already exists; re-running seeding (e.g. seedAgent which calls create internally) against a populated store; retrying a create that already succeeded.

Common situations: Test setup running twice in the same process; importing scorer definitions from a file with fixed ids; hot-reload re-executing registration code with the same module-level ids.

Related errors


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