mastra-ai/mastra · error · MastraError
EXPERIMENT_INVALID_TARGET
EXPERIMENT_INVALID_TARGET
Error message
targetType and targetId must be provided together (got targetType: ${args?.targetType ?? 'none'}, targetId: ${args?.targetId ?? 'none'}) What it means
createExperiment requires targetType and targetId to be supplied together. Providing exactly one is ambiguous (a target type with no id or vice versa), so Mastra rejects it at creation time.
Solutions
- Always pass both targetType and targetId together
- Remove both if the experiment is intentionally target-less (then don't pass scorers either)
- Coalesce partial option objects so both keys are present or both absent
Example fix
// before
await dataset.createExperiment({ targetType: 'agent' });
// after
await dataset.createExperiment({ targetType: 'agent', targetId: 'myAgent' }); Defensive patterns
Strategy: validation
Validate before calling
function validateTargetArgs(args?: { targetType?: string; targetId?: string }): void {
const hasType = args?.targetType !== undefined;
const hasId = args?.targetId !== undefined;
if (hasType !== hasId) throw new Error('targetType and targetId must be provided together');
} Type guard
function hasCompleteTarget(args?: { targetType?: string; targetId?: string }): args is { targetType: string; targetId: string } & typeof args { return args?.targetType !== undefined && args?.targetId !== undefined; } Try / catch
try {
await dataset.createExperiment(args);
} catch (e) {
if (isMastraError(e) && e.id === 'EXPERIMENT_INVALID_TARGET') {
console.error('Supply targetType and targetId together (or neither)');
} else throw e;
} Prevention
- Build target args with a helper that always sets both fields
- Avoid conditionally setting only one of the pair in config objects
- Type experiment options so the target is a single { targetType, targetId } object
When it happens
Trigger: Calling createExperiment with only targetType, or only targetId, set in args.
Common situations: Building args conditionally where one field is set but the other is undefined; copying a config and deleting a line; spreading partial options objects.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- EXPERIMENT_RESULT_MISSING_EXPERIMENT_ID
- A work item cannot relate to itself.
- COMPARE_INVALID_INPUT
- DATASET_INVALID_ID
- DATASET_ITEM_EXTERNAL_ID_INVALID
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/df08c996bceb83b9.
Report an issue: GitHub.
Appendix: source
Thrown at packages/core/src/datasets/dataset.ts:656
provenance?: ExperimentProvenance;
grouping?: { experimentSetId?: string; comparisonId?: string; variantId?: string; trialIndex?: number };
/** Dataset version to pin. Defaults to the dataset's current version. */
version?: number;
}): Promise<{
experimentId: string;
status: ExperimentStatus;
totalItems: number;
datasetVersion: number;
/** The persisted start timestamp — stable across retried creates with the same `id`. */
startedAt: Date | null;
}> {
const experimentsStore = await this.#getExperimentsStore();
const datasetsStore = await this.#getDatasetsStore();
const hasTargetType = args?.targetType !== undefined;
const hasTargetId = args?.targetId !== undefined;
if (hasTargetType !== hasTargetId) {
throw new MastraError({
id: 'EXPERIMENT_INVALID_TARGET',
text: `targetType and targetId must be provided together (got targetType: ${args?.targetType ?? 'none'}, targetId: ${args?.targetId ?? 'none'})`,
domain: 'STORAGE',
category: 'USER',
});
}
if (args?.scorers?.length && !hasTargetType) {
throw new MastraError({
id: 'EXPERIMENT_INVALID_TARGET',
text: 'scorers require a target: without a target Mastra never executes or scores items; submit flat scores via submitExperimentResult instead',
domain: 'STORAGE',
category: 'USER',
});
}
// Validate the target exists in this Mastra registry at create time so a
// typo fails fast instead of failing on the first runExperimentItem call.
if (hasTargetType) {
const resolved = await resolveTarget(this.#mastra, args!.targetType!, args!.targetId!);View on GitHub (pinned to 75dd419e61)