mastra-ai/mastra · error · MastraError

EXPERIMENT_HAS_NO_TARGET

EXPERIMENT_HAS_NO_TARGET

Error message

Experiment ${experiment.id} has no target; results must be ingested via submitExperimentResult

What it means

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.

Source

Thrown at packages/core/src/datasets/experiment/item.ts:74

 * `(experimentId, itemId, attempt)` so a retried caller (e.g. a retried
 * Temporal activity) converges on a single row.
 *
 * Scorer precedence mirrors the in-process runner: experiment `scorerIds` →
 * item `scorerIds` → dataset `scorerIds` → none. An item scorer reference to
 * an unregistered scorer is a deterministic preflight failure
 * ({@link EXPERIMENT_ITEM_SCORER_NOT_FOUND}): the target is not executed and
 * the error is recorded on the row.
 *
 * Deliberately excludes the runner's loop-level concerns: hooks, event
 * dispatch, tool mocks, and internal retries — retries/timeouts belong to the
 * caller's orchestrator.
 */
export async function executeExperimentItem(args: ExecuteExperimentItemArgs): Promise<ExecuteExperimentItemOutput> {
  const { mastra, experiment, item } = args;
  const attempt = args.attempt ?? 0;

  if (experiment.targetType === null || experiment.targetId === null) {
    throw new MastraError({
      id: 'EXPERIMENT_HAS_NO_TARGET',
      text: `Experiment ${experiment.id} has no target; results must be ingested via submitExperimentResult`,
      domain: 'STORAGE',
      category: 'USER',
    });
  }

  const resolved = await resolveTarget(
    mastra,
    experiment.targetType,
    experiment.targetId,
    experiment.agentVersion ?? undefined,
  );
  if (!resolved) {
    throw new MastraError({
      id: 'EXPERIMENT_TARGET_NOT_FOUND',
      text: `Target not found: ${experiment.targetType} "${experiment.targetId}"`,
      domain: 'STORAGE',

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Pass targetType and targetId (e.g. an agent or workflow id) when creating the experiment if you intend to execute it locally.
  2. If the experiment is intentionally target-less, ingest results with submitExperimentResult instead of runExperimentItem.
  3. Check experiment.targetType/targetId before calling runExperimentItem and branch on it.
  4. Verify the experiment record in storage wasn't created/migrated with null target fields.

Example fix

// before
await runExperimentItem({ mastra, experiment, item }); // experiment.targetId === null
// after
if (experiment.targetId == null) {
  await submitExperimentResult({ mastra, experimentId: experiment.id, input: item.input, output } );
} else {
  await runExperimentItem({ mastra, experiment, item });
}
Defensive patterns

Strategy: validation

Validate before calling

if (experiment.targetType == null || experiment.targetId == null) {
  // route to submitExperimentResult instead of local execution
}

Type guard

function hasTarget(e: { targetType: string | null; targetId: string | null }): e is { targetType: string; targetId: string } {
  return e.targetType !== null && e.targetId !== null;
}

Try / catch

try {
  await runExperimentItem({ mastra, experiment, item });
} catch (err) {
  if (err?.id === 'EXPERIMENT_HAS_NO_TARGET') return submitExperimentResult({ mastra, experimentId: experiment.id, ... });
  throw err;
}

Prevention

When it happens

Trigger: Calling runExperimentItem (directly or via local experiment execution) for an experiment created without a target, e.g. created for manual/external result ingestion.

Common situations: 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.

Related errors


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