{"record":{"id":"6ceff51640adca1b","repo":"mastra-ai/mastra","slug":"experiment-result-input-id-does-not-belong-to-e","errorCode":null,"errorMessage":"Experiment result ${input.id} does not belong to experiment ${input.experimentId}","messagePattern":"Experiment result (.+?) does not belong to experiment (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/storage/domains/experiments/inmemory.ts","lineNumber":261,"sourceCode":"      status: input.status ?? null,\n      tags: input.tags ?? null,\n      comment: existing.comment ?? null,\n      toolMockReport: input.toolMockReport ?? null,\n      organizationId: input.organizationId ?? null,\n      projectId: input.projectId ?? null,\n      createdAt: existing.createdAt,\n    };\n    this.db.experimentResults.set(existing.id, cloneExperimentResultMetadata(replaced));\n    return cloneExperimentResultMetadata(replaced);\n  }\n\n  async updateExperimentResult(input: UpdateExperimentResultInput): Promise<ExperimentResult> {\n    const existing = this.db.experimentResults.get(input.id);\n    if (!existing) {\n      throw new Error(`Experiment result not found: ${input.id}`);\n    }\n    if (input.experimentId && existing.experimentId !== input.experimentId) {\n      throw new Error(`Experiment result ${input.id} does not belong to experiment ${input.experimentId}`);\n    }\n    const updated: ExperimentResult = {\n      ...existing,\n      status: input.status !== undefined ? input.status : existing.status,\n      tags: input.tags !== undefined ? input.tags : existing.tags,\n      comment: input.comment !== undefined ? input.comment : existing.comment,\n    };\n    this.db.experimentResults.set(input.id, cloneExperimentResultMetadata(updated));\n    return cloneExperimentResultMetadata(updated);\n  }\n\n  async getExperimentResultById(args: {\n    id: string;\n    filters?: ExperimentTenancyFilters;\n  }): Promise<ExperimentResult | null> {\n    const row = this.db.experimentResults.get(args.id);\n    if (!row) return null;\n    if (args.filters?.organizationId !== undefined && (row.organizationId ?? null) !== args.filters.organizationId) {","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/storage/domains/experiments/inmemory.ts#L243-L279","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fetch the result first and omit experimentId, or pass result.experimentId as-is.","Fix id pairing so each result id is updated with its own experiment id.","If results truly should move experiments, delete and recreate under the correct experiment instead of updating.","Add a pre-check comparing result.experimentId to the intended experiment before updating."],"exampleFix":"// before\nawait storage.experiments.updateExperimentResult({ id: resultId, experimentId: wrongExpId, status: 'failed' });\n// after\nconst result = await storage.experiments.getExperimentResult({ id: resultId });\nawait storage.experiments.updateExperimentResult({ id: resultId, experimentId: result.experimentId, status: 'failed' });","handlingStrategy":"validation","validationCode":"const res = await storage.experiments.getExperimentResult({ id: resultId });\nif (res && experimentId && res.experimentId !== experimentId) {\n  throw new Error(`Result ${resultId} belongs to ${res.experimentId}, not ${experimentId}`);\n}","typeGuard":"function resultBelongsToExperiment(result: { experimentId: string }, experimentId: string): boolean {\n  return result.experimentId === experimentId;\n}","tryCatchPattern":"try {\n  await storage.experiments.updateExperimentResult({ id: resultId, experimentId, status });\n} catch (e) {\n  if (String(e).includes('does not belong to experiment')) {\n    // id/experiment mismatch — re-pair ids from the source run\n  } else throw e;\n}","preventionTips":["Keep resultId and experimentId paired in a single record, never in parallel arrays.","Omit experimentId on updates when you don't need the cross-check.","Never reuse a result id across different experiment runs."],"tags":["storage","experiments","inmemory","ownership-mismatch"],"backgroundTag":"resource-ownership-mismatch","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}