mastra-ai/mastra · error · MastraError

EXPERIMENT_ID_CONFLICT

EXPERIMENT_ID_CONFLICT

Error message

Experiment id ${args.id} already exists and does not match this experiment's dataset or target

What it means

createExperiment supports a caller-supplied experiment id (args.id). If an experiment with that id already exists but was created against a different dataset or target, reusing the id would silently mix results across shapes, so it is rejected. Same datasetId + targetType + targetId is accepted (idempotent reuse).

Source

Thrown at packages/core/src/datasets/dataset.ts:705

      throw new MastraError({
        id: 'DATASET_NOT_FOUND',
        text: `Dataset not found: ${this.id}`,
        domain: 'STORAGE',
        category: 'USER',
      });
    }

    // Idempotent create: a retried create with the same id returns the
    // existing experiment instead of failing or duplicating.
    if (args?.id) {
      const existing = await experimentsStore.getExperimentById({ id: args.id, filters: this.#scope });
      if (existing) {
        const sameShape =
          existing.datasetId === this.id &&
          existing.targetType === (args.targetType ?? null) &&
          existing.targetId === (args.targetId ?? null);
        if (!sameShape) {
          throw new MastraError({
            id: 'EXPERIMENT_ID_CONFLICT',
            text: `Experiment id ${args.id} already exists and does not match this experiment's dataset or target`,
            domain: 'STORAGE',
            category: 'USER',
          });
        }
        // Repair a half-created record: a prior create that crashed between
        // createExperiment and the status update leaves the row 'pending'.
        // A retried create finishes the job so the caller never observes a
        // permanently-pending experiment.
        let status = existing.status;
        let startedAt = existing.startedAt ?? null;
        if (existing.status === 'pending') {
          startedAt = new Date();
          await experimentsStore.updateExperiment({ id: existing.id, status: 'running', startedAt });
          status = 'running';
        }
        return {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Use a new unique experiment id
  2. If re-running the same evaluation intentionally, keep dataset and target identical so the id matches
  3. Delete the old experiment if it should be replaced, then recreate with the same id

Example fix

// before
await dataset.createExperiment({ id: 'nightly-1', targetType: 'agent', targetId: 'newAgent' }); // 'nightly-1' used agent 'oldAgent'
// after
await dataset.createExperiment({ id: `nightly-1-${targetId}`, targetType: 'agent', targetId: 'newAgent' });
Defensive patterns

Strategy: validation

Validate before calling

const existing = await experimentsStore.getExperimentById({ id: args.id, filters: scope });
const conflicts = existing && (existing.datasetId !== dataset.id || existing.targetType !== (args.targetType ?? null) || existing.targetId !== (args.targetId ?? null));
if (conflicts) throw new Error(`Experiment id ${args.id} is bound to a different dataset/target`);

Type guard

function idIsReusable(existing: { datasetId: string; targetType: string | null; targetId: string | null } | null, datasetId: string, args: { targetType?: string; targetId?: string }): boolean { return !existing || (existing.datasetId === datasetId && existing.targetType === (args.targetType ?? null) && existing.targetId === (args.targetId ?? null)); }

Try / catch

try {
  await dataset.createExperiment(args);
} catch (e) {
  if (isMastraError(e) && e.id === 'EXPERIMENT_ID_CONFLICT') {
    console.warn(`Id ${args.id} taken by a different shape; generating a new id`);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling createExperiment with an explicit args.id that collides with an existing experiment bound to a different dataset or target.

Common situations: Hardcoded experiment ids in CI re-run against a changed agent; reusing an id after renaming the target; ids generated deterministically from a config that changed.

Related errors


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