mastra-ai/mastra · error · HTTPException

targetType and targetId are required to start an experiment

Error message

targetType and targetId are required to start an experiment

What it means

A client-input HTTPException(400): the trigger/start-experiment route allows a 'dry' path that returns a pre-created experiment shell only when targetType/targetId are resolvable; otherwise it requires both fields to actually start an experiment. The request reached the route without the mandatory targetType or targetId body/query parameters.

Source

Thrown at packages/server/src/server/handlers/datasets.ts:795

          metadata,
          version,
          provenance,
          grouping,
        });
        return {
          experimentId: created.experimentId,
          status: created.status,
          totalItems: created.totalItems,
          datasetVersion: created.datasetVersion,
          succeededCount: 0,
          failedCount: 0,
          startedAt: created.startedAt,
          completedAt: null,
          results: [],
        };
      }
      if (!targetType || !targetId) {
        throw new HTTPException(400, { message: 'targetType and targetId are required to start an experiment' });
      }
      const result = await ds.startExperimentAsync({
        targetType,
        targetId,
        name,
        description,
        metadata,
        scorers: scorerIds,
        version,
        agentVersion,
        maxConcurrency,
        provenance,
        grouping,
        requestContext,
        versions,
      });
      // Return shape matching experimentSummaryResponseSchema
      return {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Include both targetType and targetId in the request payload (e.g. targetType: 'agent' | 'workflow' and the id of that target).
  2. Verify the client SDK/serialization actually sends the fields (no undefined dropped by JSON.stringify).
  3. Update to a matching client/server version if field names diverged.

Example fix

// before
await fetch('/api/datasets/ds_1/experiments', { method: 'POST', body: JSON.stringify({ name: 'run' }) });
// after
await fetch('/api/datasets/ds_1/experiments', { method: 'POST', body: JSON.stringify({ name: 'run', targetType: 'agent', targetId: 'my-agent' }) });
Defensive patterns

Strategy: validation

Validate before calling

if (!targetType || !targetId) {
  throw new Error('targetType and targetId are required to start an experiment');
}

Type guard

function canStartExperiment(p: unknown): p is { targetType: string; targetId: string } {
  const q = p as any;
  return typeof q?.targetType === 'string' && q.targetType.length > 0 && typeof q?.targetId === 'string' && q.targetId.length > 0;
}

Try / catch

try {
  await triggerExperiment(payload);
} catch (e) {
  if ((e as Error).message.includes('targetType and targetId are required')) {
    // correct the payload before retry
  }
}

Prevention

When it happens

Trigger: POST to the start/trigger experiment endpoint omitting either targetType or targetId while not hitting the pre-created-experiment branch (no already-created experiment with results shell).

Common situations: Frontend forms not sending the target fields; API consumers copying an example that only created a placeholder experiment; renaming of fields in client SDKs causing targetType/targetId to serialize as undefined.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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