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
- Use a new unique experiment id
- If re-running the same evaluation intentionally, keep dataset and target identical so the id matches
- 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
- Generate experiment ids with dataset/target baked in (e.g. `${datasetId}-${targetId}-${runDate}`)
- Only reuse explicit ids for idempotent re-runs of the identical dataset+target
- Clean up old experiments before recycling their ids
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
- Thread with id ${newThreadId} already exists
- EXPERIMENT_NO_ITEMS
- EXPERIMENT_NOT_FOUND
- EXPERIMENT_RESULT_MISSING_EXPERIMENT_ID
- EXPERIMENT_INVALID_TARGET
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/75776c7395bc049b.
Report an issue: GitHub.