mastra-ai/mastra · error · MastraError

EXPERIMENT_ALREADY_FINALIZED

EXPERIMENT_ALREADY_FINALIZED

Error message

Experiment ${args.experimentId} is already ${experiment.status}; no further items can be run

What it means

runExperimentItem refuses to execute items on an experiment whose status is already 'completed' or 'failed'. A finalized experiment is immutable; running further items would corrupt its results or scores.

Source

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

  async runExperimentItem(args: {
    experimentId: string;
    itemId: string;
    /** Zero-based repetition index for repeated trials. Defaults to `0`. */
    attempt?: number;
    /** Request context merged with the item's own request context (item wins). */
    requestContext?: Record<string, unknown>;
  }): Promise<{ result: ExperimentResult; scores: Awaited<ReturnType<typeof executeExperimentItem>>['scores'] }> {
    const experiment = await this.#getOwnedExperiment(args.experimentId);
    if (experiment.targetType === null) {
      throw new MastraError({
        id: 'EXPERIMENT_HAS_NO_TARGET',
        text: `Experiment ${args.experimentId} has no target; ingest results via submitExperimentResult instead`,
        domain: 'STORAGE',
        category: 'USER',
      });
    }
    if (experiment.status === 'completed' || experiment.status === 'failed') {
      throw new MastraError({
        id: 'EXPERIMENT_ALREADY_FINALIZED',
        text: `Experiment ${args.experimentId} is already ${experiment.status}; no further items can be run`,
        domain: 'STORAGE',
        category: 'USER',
      });
    }

    const datasetsStore = await this.#getDatasetsStore();
    const dataset = await datasetsStore.getDatasetById({ id: this.id, filters: this.#scope });
    const item = await datasetsStore.getItemById({
      id: args.itemId,
      datasetVersion: experiment.datasetVersion ?? undefined,
    });
    if (!item || item.datasetId !== this.id) {
      throw new MastraError({
        id: 'DATASET_ITEM_NOT_FOUND',
        text: `Item ${args.itemId} not found in dataset ${this.id} at version ${experiment.datasetVersion}`,
        domain: 'STORAGE',

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Check experiment.status before calling; skip or create a new experiment if finalized
  2. Create a new experiment (new id) to re-run the evaluation
  3. Handle status transitions in your runner loop: stop when status becomes completed/failed
  4. Remove retry logic that replays items against finalized experiments

Example fix

// before
await dataset.runExperimentItem({ experimentId: 'exp-1', itemId: 'item-3' });
// after
const exp = await getExperiment('exp-1');
if (exp.status === 'completed' || exp.status === 'failed') {
  exp = await dataset.createExperiment({ id: 'exp-1-rerun', ... });
}
await dataset.runExperimentItem({ experimentId: exp.id, itemId: 'item-3' });
Defensive patterns

Strategy: validation

Validate before calling

const exp = await getExperimentById(experimentId);
if (exp.status === 'completed' || exp.status === 'failed') throw new Error('Experiment finalized; create a new one to re-run');

Type guard

function isRunnable(exp) { return exp.status !== 'completed' && exp.status !== 'failed'; }

Try / catch

try {
  await dataset.runExperimentItem(args);
} catch (e) {
  if (isMastraError(e) && e.id === 'EXPERIMENT_ALREADY_FINALIZED') {
    // stop the loop or create a fresh experiment for a re-run
  } else throw e;
}

Prevention

When it happens

Trigger: Calling runExperimentItem for an experiment whose status is 'completed' or 'failed' — e.g. all items already ran, the experiment failed earlier, or a stale client retries after finalization.

Common situations: Re-running an eval script without checking status; concurrent workers racing on the last item after another finalized the experiment; retry logic replaying an item against a failed experiment; resuming an old experiment id from a previous run.

Related errors


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