mastra-ai/mastra · error · MastraError

EXPERIMENT_NOT_FOUND

EXPERIMENT_NOT_FOUND

Error message

Experiment not found: ${experimentId}

What it means

Thrown by the internal #assertExperimentOwnership guard when getExperimentById returns no experiment, or the experiment's datasetId does not match this Dataset handle's id. This ensures a Dataset can only read/update/delete experiments that belong to it (and are within its scope).

Solutions

  1. Verify the experimentId exists via the experiments store or listExperiments
  2. Confirm the experiment belongs to this dataset (experiment.datasetId === dataset.id)
  3. Re-obtain the Dataset handle for the correct dataset that owns the experiment
  4. Check that the Dataset handle's scope filters match the environment that created the experiment

Example fix

// before
await wrongDataset.deleteExperiment({ experimentId: id });
// after
const owningDataset = await mastra.getDataset(experiment.datasetId);
await owningDataset.deleteExperiment({ experimentId: id });
Defensive patterns

Strategy: try-catch

Validate before calling

const experiment = await experimentsStore.getExperimentById({ id: experimentId, filters: scope });
if (!experiment || experiment.datasetId !== dataset.id) throw new Error(`Experiment ${experimentId} not owned by dataset ${dataset.id}`);

Type guard

function isOwnedExperiment<T extends { datasetId: string }>(exp: T | undefined | null, datasetId: string): exp is T { return !!exp && exp.datasetId === datasetId; }

Try / catch

try {
  await dataset.deleteExperiment({ experimentId });
} catch (e) {
  if (isMastraError(e) && e.id === 'EXPERIMENT_NOT_FOUND') {
    console.warn(`Experiment ${experimentId} not found for this dataset; skipping`);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling listExperimentResults, updateExperimentResult, or deleteExperiment with an experimentId that does not exist, is scoped out by filters, or belongs to a different dataset.

Common situations: Copy-pasting an experiment id from another dataset; using an id from a different Mastra instance or storage backend; id typo; experiment was deleted; wrong scope/tenant on the Dataset handle.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

    });
  }

  /**
   * Verify the experiment belongs to this dataset (and, by extension, to the
   * handle's tenancy scope which was enforced when the handle was minted).
   * Throws NOT_FOUND on missing or cross-dataset experiments so cross-tenant
   * mutation via a valid scoped handle + a known foreign experimentId is
   * rejected.
   */
  async #assertExperimentOwnership(experimentId: string): Promise<void> {
    await this.#assertScope();
    const experimentsStore = await this.#getExperimentsStore();
    const experiment = await experimentsStore.getExperimentById({
      id: experimentId,
      filters: this.#scope,
    });
    if (!experiment || experiment.datasetId !== this.id) {
      throw new MastraError({
        id: 'EXPERIMENT_NOT_FOUND',
        text: `Experiment not found: ${experimentId}`,
        domain: 'STORAGE',
        category: 'USER',
      });
    }
  }

  /**
   * Get a specific experiment (run) by ID.
   */
  async getExperiment(args: { experimentId: string }) {
    await this.#assertScope();
    const experimentsStore = await this.#getExperimentsStore();
    const experiment = await experimentsStore.getExperimentById({
      id: args.experimentId,
      filters: this.#scope,
    });

View on GitHub (pinned to 75dd419e61)