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.
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)
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
- Either context or contextExtractor is required for Context R
- Context array cannot be empty if provided
- createMultiTurnJudgeScorer: options.scale must be a finite n
- Both baselineResponse and noisyQuery are required for Noise
- Google RBAC roleMapping is required.
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/b7bcb883db8a27eb.
Report an issue: GitHub.