{"record":{"id":"64e899bcc38c429f","repo":"mastra-ai/mastra","slug":"experiment-has-no-target-64e899","errorCode":"EXPERIMENT_HAS_NO_TARGET","errorMessage":"Experiment ${experiment.id} has no target; results must be ingested via submitExperimentResult","messagePattern":"Experiment (.+?) has no target; results must be ingested via submitExperimentResult","errorType":"error_code","errorClass":"MastraError","httpStatus":null,"severity":"error","filePath":"packages/core/src/datasets/experiment/item.ts","lineNumber":74,"sourceCode":" * `(experimentId, itemId, attempt)` so a retried caller (e.g. a retried\n * Temporal activity) converges on a single row.\n *\n * Scorer precedence mirrors the in-process runner: experiment `scorerIds` →\n * item `scorerIds` → dataset `scorerIds` → none. An item scorer reference to\n * an unregistered scorer is a deterministic preflight failure\n * ({@link EXPERIMENT_ITEM_SCORER_NOT_FOUND}): the target is not executed and\n * the error is recorded on the row.\n *\n * Deliberately excludes the runner's loop-level concerns: hooks, event\n * dispatch, tool mocks, and internal retries — retries/timeouts belong to the\n * caller's orchestrator.\n */\nexport async function executeExperimentItem(args: ExecuteExperimentItemArgs): Promise<ExecuteExperimentItemOutput> {\n  const { mastra, experiment, item } = args;\n  const attempt = args.attempt ?? 0;\n\n  if (experiment.targetType === null || experiment.targetId === null) {\n    throw new MastraError({\n      id: 'EXPERIMENT_HAS_NO_TARGET',\n      text: `Experiment ${experiment.id} has no target; results must be ingested via submitExperimentResult`,\n      domain: 'STORAGE',\n      category: 'USER',\n    });\n  }\n\n  const resolved = await resolveTarget(\n    mastra,\n    experiment.targetType,\n    experiment.targetId,\n    experiment.agentVersion ?? undefined,\n  );\n  if (!resolved) {\n    throw new MastraError({\n      id: 'EXPERIMENT_TARGET_NOT_FOUND',\n      text: `Target not found: ${experiment.targetType} \"${experiment.targetId}\"`,\n      domain: 'STORAGE',","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/datasets/experiment/item.ts#L56-L92","documentation":"executeExperimentItem refuses to run an experiment whose record has targetType===null or targetId===null. Experiments that are not linked to an agent/workflow target are 'externally ingested': their results must be supplied via submitExperimentResult, not executed locally. Throwing MastraError EXPERIMENT_HAS_NO_TARGET prevents silently executing against nothing.","triggerScenarios":"Calling runExperimentItem (directly or via local experiment execution) for an experiment created without a target, e.g. created for manual/external result ingestion.","commonSituations":"Creating an experiment via the datasets API/HTTP without passing targetId/targetType, then attempting to execute it; experiments seeded for CI-ingested eval results; migrating experiments where the target linkage was lost.","solutions":["Pass targetType and targetId (e.g. an agent or workflow id) when creating the experiment if you intend to execute it locally.","If the experiment is intentionally target-less, ingest results with submitExperimentResult instead of runExperimentItem.","Check experiment.targetType/targetId before calling runExperimentItem and branch on it.","Verify the experiment record in storage wasn't created/migrated with null target fields."],"exampleFix":"// before\nawait runExperimentItem({ mastra, experiment, item }); // experiment.targetId === null\n// after\nif (experiment.targetId == null) {\n  await submitExperimentResult({ mastra, experimentId: experiment.id, input: item.input, output } );\n} else {\n  await runExperimentItem({ mastra, experiment, item });\n}","handlingStrategy":"validation","validationCode":"if (experiment.targetType == null || experiment.targetId == null) {\n  // route to submitExperimentResult instead of local execution\n}","typeGuard":"function hasTarget(e: { targetType: string | null; targetId: string | null }): e is { targetType: string; targetId: string } {\n  return e.targetType !== null && e.targetId !== null;\n}","tryCatchPattern":"try {\n  await runExperimentItem({ mastra, experiment, item });\n} catch (err) {\n  if (err?.id === 'EXPERIMENT_HAS_NO_TARGET') return submitExperimentResult({ mastra, experimentId: experiment.id, ... });\n  throw err;\n}","preventionTips":["Always set targetType/targetId when creating experiments you intend to execute locally.","Branch explicitly: target-less experiments are ingest-only by design.","Validate experiment records coming from storage/HTTP before executing.","Document in your pipeline that manual/external experiments must use submitExperimentResult."],"tags":["configuration","experiments","validation"],"backgroundTag":"missing-target-configuration","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}