{"record":{"id":"69c16926dbeef74c","repo":"mastra-ai/mastra","slug":"experiment-has-no-target","errorCode":"EXPERIMENT_HAS_NO_TARGET","errorMessage":"Experiment ${args.experimentId} has no target; ingest results via submitExperimentResult instead","messagePattern":"Experiment (.+?) has no target; ingest results via submitExperimentResult instead","errorType":"error_code","errorClass":"MastraError","httpStatus":null,"severity":"error","filePath":"packages/core/src/datasets/dataset.ts","lineNumber":827,"sourceCode":"   * Built for caller-driven loops (mode 2): a durable orchestrator (e.g. a\n   * Temporal workflow) fans out one call per item and owns retries/timeouts —\n   * a retried call converges on the same row. Requires an experiment created\n   * with a target via {@link Dataset.createExperiment}.\n   *\n   * Scorer precedence: experiment `scorers` → item `scorerIds` → dataset\n   * `scorerIds` → none.\n   */\n  async runExperimentItem(args: {\n    experimentId: string;\n    itemId: string;\n    /** Zero-based repetition index for repeated trials. Defaults to `0`. */\n    attempt?: number;\n    /** Request context merged with the item's own request context (item wins). */\n    requestContext?: Record<string, unknown>;\n  }): Promise<{ result: ExperimentResult; scores: Awaited<ReturnType<typeof executeExperimentItem>>['scores'] }> {\n    const experiment = await this.#getOwnedExperiment(args.experimentId);\n    if (experiment.targetType === null) {\n      throw new MastraError({\n        id: 'EXPERIMENT_HAS_NO_TARGET',\n        text: `Experiment ${args.experimentId} has no target; ingest results via submitExperimentResult instead`,\n        domain: 'STORAGE',\n        category: 'USER',\n      });\n    }\n    if (experiment.status === 'completed' || experiment.status === 'failed') {\n      throw new MastraError({\n        id: 'EXPERIMENT_ALREADY_FINALIZED',\n        text: `Experiment ${args.experimentId} is already ${experiment.status}; no further items can be run`,\n        domain: 'STORAGE',\n        category: 'USER',\n      });\n    }\n\n    const datasetsStore = await this.#getDatasetsStore();\n    const dataset = await datasetsStore.getDatasetById({ id: this.id, filters: this.#scope });\n    const item = await datasetsStore.getItemById({","sourceCodeStart":809,"sourceCodeEnd":845,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/datasets/dataset.ts#L809-L845","documentation":"runExperimentItem executes the bound target (agent/tool/workflow) for one dataset item, so it requires the experiment to have a target. If the experiment was created as targetless (targetType null) — meaning results are supplied externally — Mastra refuses to run anything and directs you to submitExperimentResult.","triggerScenarios":"Calling dataset.runExperimentItem({ experimentId, itemId }) on an experiment created with no target (targetType null), typically one populated via submitExperimentResult from an external evaluation pipeline.","commonSituations":"Mixing the two execution models: an external harness created the experiment, then a developer tries to run it locally; a helper script reuses an experiment id that happened to be created targetless; refactoring moved from Mastra-driven to external evaluation without updating callers.","solutions":["Check experiment.targetType before running; if null, use submitExperimentResult instead","Create a new experiment with a target (targetType/targetId) if you want Mastra to execute items","Route external results through submitExperimentResult in your pipeline code"],"exampleFix":"// before\nawait dataset.runExperimentItem({ experimentId: 'exp-1', itemId: 'item-9' }); // exp-1 is targetless\n// after\nconst exp = await getExperiment('exp-1');\nif (exp.targetType === null) {\n  await dataset.submitExperimentResult({ experimentId: 'exp-1', itemId: 'item-9', result: myResult });\n}","handlingStrategy":"validation","validationCode":"const exp = await getExperimentById(experimentId);\nif (!exp || exp.targetType === null) throw new Error('Experiment is targetless; use submitExperimentResult');","typeGuard":"function hasTarget(exp) { return exp !== null && exp.targetType !== null && exp.targetId !== null; }","tryCatchPattern":"try {\n  await dataset.runExperimentItem(args);\n} catch (e) {\n  if (isMastraError(e) && e.id === 'EXPERIMENT_HAS_NO_TARGET') {\n    await dataset.submitExperimentResult({ experimentId: args.experimentId, ... });\n  } else throw e;\n}","preventionTips":["Track experiment mode (targeted vs targetless) in your runner config","Branch on experiment.targetType before choosing run vs submit APIs","Avoid sharing one experiment id between external pipelines and local runs"],"tags":["storage","experiments","api-misuse","user-error"],"backgroundTag":"wrong-api-for-experiment-mode","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}