mastra-ai/mastra · error · MastraError
NO_SCORERS_PROVIDED
NO_SCORERS_PROVIDED
Error message
At least one scorer or gate must be provided
What it means
An eval run must have something to evaluate: when `scorers` is an array it must be non-empty, unless the run supplies gates (top-level `gates`) or per-turn assertions, which alone are valid. This error means runEvals was invoked with no scoring or gating criteria at all, so the run would have no observable outcome.
Solutions
- Pass at least one scorer, e.g. `scorers: [myScorer]`
- Add gates (`gates: [...]`) or per-turn assertions if you intend a gate-only run
- Check the code that builds the scorers array — log its length before runEvals and fail early if 0
Example fix
// before
runEvals({ target: agent, scorers: [], data });
// after
runEvals({ target: agent, scorers: [answerRelevanceScorer], data }); Defensive patterns
Strategy: validation
Validate before calling
if (Array.isArray(scorers) && scorers.length === 0 && !gates?.length && !hasTurnAssertions(data)) {
throw new Error('runEvals requires at least one scorer or gate');
} Type guard
function hasEvaluationCriteria(scorers: unknown[], gates?: unknown[]): boolean {
return scorers.length > 0 || (gates?.length ?? 0) > 0;
} Try / catch
try {
await runEvals({ target, scorers, data, gates });
} catch (e) {
if (e instanceof MastraError && e.id === 'NO_SCORERS_PROVIDED') {
console.error('No scorers/gates configured — check flag-gated scorer loading');
} else throw e;
} Prevention
- Fail fast where the scorers array is built: assert length > 0
- Remember gate-only runs are valid; don't add dummy scorers to bypass the check
- Log the resolved scorer list in config-driven setups
When it happens
Trigger: Calling runEvals with `scorers: []` and no gates/per-turn assertions; passing an empty scorers array built dynamically after filtering by name; forgetting to load scorer registrations in a config-driven setup.
Common situations: Config files where all scorers were commented out or filtered out by an env flag; programmatically assembling scorer lists that end up empty; misunderstanding that gate-only runs are allowed but no-criteria runs are not.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- Both baselineResponse and noisyQuery are required for Noise…
- Context array cannot be empty if provided
- createMultiTurnJudgeScorer: options.scale must be a finite…
- Either context or contextExtractor is required for Context…
- A custom capture schema requires an onExtracted hook that…
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/b7bcb883db8a27eb.
Report an issue: GitHub.
Appendix: source
Thrown at packages/core/src/evals/run/index.ts:773
hasAnyTurnAssertions = true;
// Validate per-turn threshold bounds upfront so errors surface before execution.
for (const entry of turn.scorers) {
if (isScorerWithThreshold(entry)) {
validateThresholdConfig(entry.threshold, entry.scorer.id);
}
}
}
}
}
}
// Validate scorers
if (Array.isArray(scorers)) {
// Gate-only runs are valid: a non-empty gates array satisfies the
// "at least one scorer" requirement even when scorers is empty.
// Per-turn gates/scorers also satisfy it.
if (scorers.length === 0 && !hasGates && !hasAnyTurnAssertions) {
throw new MastraError({
domain: 'SCORER',
id: 'NO_SCORERS_PROVIDED',
category: 'USER',
text: 'At least one scorer or gate must be provided',
});
}
} else if (isWorkflow(target) && isWorkflowScorerConfig(scorers)) {
const hasScorers =
(scorers.workflow && scorers.workflow.length > 0) ||
(scorers.steps && Object.keys(scorers.steps).length > 0) ||
(scorers.trajectory && scorers.trajectory.length > 0);
if (!hasScorers) {
throw new MastraError({
domain: 'SCORER',
id: 'NO_SCORERS_PROVIDED',
category: 'USER',
text: 'At least one workflow, step, or trajectory scorer must be provided',View on GitHub (pinned to 75dd419e61)