mastra-ai/mastra · error · Error

Experiment result ${input.id} does not belong to experiment

Error message

Experiment result ${input.id} does not belong to experiment ${input.experimentId}

What it means

Ownership guard on updateExperimentResult: if the caller supplies an experimentId and the stored result belongs to a different experiment, the update is rejected. This prevents cross-experiment result contamination.

Source

Thrown at packages/core/src/storage/domains/experiments/inmemory.ts:261

      status: input.status ?? null,
      tags: input.tags ?? null,
      comment: existing.comment ?? null,
      toolMockReport: input.toolMockReport ?? null,
      organizationId: input.organizationId ?? null,
      projectId: input.projectId ?? null,
      createdAt: existing.createdAt,
    };
    this.db.experimentResults.set(existing.id, cloneExperimentResultMetadata(replaced));
    return cloneExperimentResultMetadata(replaced);
  }

  async updateExperimentResult(input: UpdateExperimentResultInput): Promise<ExperimentResult> {
    const existing = this.db.experimentResults.get(input.id);
    if (!existing) {
      throw new Error(`Experiment result not found: ${input.id}`);
    }
    if (input.experimentId && existing.experimentId !== input.experimentId) {
      throw new Error(`Experiment result ${input.id} does not belong to experiment ${input.experimentId}`);
    }
    const updated: ExperimentResult = {
      ...existing,
      status: input.status !== undefined ? input.status : existing.status,
      tags: input.tags !== undefined ? input.tags : existing.tags,
      comment: input.comment !== undefined ? input.comment : existing.comment,
    };
    this.db.experimentResults.set(input.id, cloneExperimentResultMetadata(updated));
    return cloneExperimentResultMetadata(updated);
  }

  async getExperimentResultById(args: {
    id: string;
    filters?: ExperimentTenancyFilters;
  }): Promise<ExperimentResult | null> {
    const row = this.db.experimentResults.get(args.id);
    if (!row) return null;
    if (args.filters?.organizationId !== undefined && (row.organizationId ?? null) !== args.filters.organizationId) {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Fetch the result first and omit experimentId, or pass result.experimentId as-is.
  2. Fix id pairing so each result id is updated with its own experiment id.
  3. If results truly should move experiments, delete and recreate under the correct experiment instead of updating.
  4. Add a pre-check comparing result.experimentId to the intended experiment before updating.

Example fix

// before
await storage.experiments.updateExperimentResult({ id: resultId, experimentId: wrongExpId, status: 'failed' });
// after
const result = await storage.experiments.getExperimentResult({ id: resultId });
await storage.experiments.updateExperimentResult({ id: resultId, experimentId: result.experimentId, status: 'failed' });
Defensive patterns

Strategy: validation

Validate before calling

const res = await storage.experiments.getExperimentResult({ id: resultId });
if (res && experimentId && res.experimentId !== experimentId) {
  throw new Error(`Result ${resultId} belongs to ${res.experimentId}, not ${experimentId}`);
}

Type guard

function resultBelongsToExperiment(result: { experimentId: string }, experimentId: string): boolean {
  return result.experimentId === experimentId;
}

Try / catch

try {
  await storage.experiments.updateExperimentResult({ id: resultId, experimentId, status });
} catch (e) {
  if (String(e).includes('does not belong to experiment')) {
    // id/experiment mismatch — re-pair ids from the source run
  } else throw e;
}

Prevention

When it happens

Trigger: updateExperimentResult({ id, experimentId }) where resultId and experimentId come from different runs; swapped variables when updating several results in a loop; reusing a cached result id with a new experiment id.

Common situations: Batch result-update loops with misaligned arrays of ids and experimentIds; merging data from two experiment runs; copy-pasted update code with the wrong experiment id interpolated.

Related errors


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