mastra-ai/mastra · error · MastraError
EXPERIMENT_HAS_TARGET
EXPERIMENT_HAS_TARGET
Error message
Experiment ${args.experimentId} has a target (${experiment.targetType} "${experiment.targetId}"); results are produced by Mastra, not ingested. Use runExperimentItem instead. What it means
submitExperimentResult ingests externally produced results and is only valid for targetless experiments (targetType null). If the experiment has a bound target, Mastra itself produces results via runExperimentItem, so external ingestion is rejected to prevent double/conflicting results.
Source
Thrown at packages/core/src/datasets/dataset.ts:919
attempt?: number;
input?: unknown;
output?: unknown;
groundTruth?: unknown;
error?: { message: string; stack?: string; code?: string } | null;
startedAt?: Date;
completedAt?: Date;
traceId?: string;
scores?: {
scorerId: string;
scorerName?: string;
score: number;
reason?: string;
metadata?: Record<string, unknown>;
}[];
}): Promise<ExperimentResult> {
const experiment = await this.#getOwnedExperiment(args.experimentId);
if (experiment.targetType !== null) {
throw new MastraError({
id: 'EXPERIMENT_HAS_TARGET',
text: `Experiment ${args.experimentId} has a target (${experiment.targetType} "${experiment.targetId}"); results are produced by Mastra, not ingested. Use runExperimentItem instead.`,
domain: 'STORAGE',
category: 'USER',
});
}
if (experiment.status === 'completed' || experiment.status === 'failed') {
throw new MastraError({
id: 'EXPERIMENT_ALREADY_FINALIZED',
text: `Experiment ${args.experimentId} is already ${experiment.status}; no further results can be submitted`,
domain: 'STORAGE',
category: 'USER',
});
}
const datasetsStore = await this.#getDatasetsStore();
const item = await datasetsStore.getItemById({
id: args.itemId,View on GitHub (pinned to 75dd419e61)
Solutions
- Check experiment.targetType; only call submitExperimentResult when it is null
- Use runExperimentItem for experiments with targets and let Mastra produce the results
- Create a separate targetless experiment if results genuinely come from outside Mastra
Example fix
// before
await dataset.submitExperimentResult({ experimentId: 'exp-1', itemId: 'item-1', ... }); // exp-1 targets agent
// after
if (exp.targetType === null) {
await dataset.submitExperimentResult({ ... });
} else {
await dataset.runExperimentItem({ experimentId: 'exp-1', itemId: 'item-1' });
} Defensive patterns
Strategy: validation
Validate before calling
const exp = await getExperimentById(experimentId);
if (exp && exp.targetType !== null) throw new Error('Experiment has a target; use runExperimentItem'); Type guard
function isTargetless(exp) { return exp !== null && exp.targetType === null; } Try / catch
try {
await dataset.submitExperimentResult(args);
} catch (e) {
if (isMastraError(e) && e.id === 'EXPERIMENT_HAS_TARGET') {
await dataset.runExperimentItem({ experimentId: args.experimentId, itemId: args.itemId });
} else throw e;
} Prevention
- Gate ingestion code paths on experiment.targetType === null
- Keep targeted and targetless experiment flows in separate pipelines
- Name experiment ids to encode mode, e.g. 'ext-' prefix for targetless
When it happens
Trigger: Calling dataset.submitExperimentResult({ experimentId, ... }) on an experiment created with targetType/targetId set (e.g. bound to an agent or tool).
Common situations: Pipelines that submit results for all experiments indiscriminately; a target was added to an experiment that previously accepted external results; copying ingestion code between targetless and targeted experiment flows.
Related errors
- EXPERIMENT_HAS_NO_TARGET
- EXPERIMENT_ALREADY_FINALIZED
- EXPERIMENTS_STORE_NOT_AVAILABLE
- DATASET_ITEM_NOT_FOUND
- Storage not configured. Configure storage in Mastra instance
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/9a0dbea309bafc99.
Report an issue: GitHub.