mastra-ai/mastra · error · Error
Persisted score is missing spanId for traceId: ${target.trac
Error message
Persisted score is missing spanId for traceId: ${target.traceId} What it means
In scoreTraceBatch, after a scorer runs, the persisted spanId is resolved as score.spanId ?? target.spanId. If both are absent, this Error is thrown because a persisted score row must be attributable to a span. It indicates the scorer run produced a score without a span association and the caller did not supply one either.
Source
Thrown at packages/core/src/evals/scoreTraces/scoreTracesWorkflow.ts:337
failedCount: number;
results: ScoreTraceBatchResult[];
}> {
const results = await pMap(
targets,
async (target, index): Promise<ScoreTraceBatchResult> => {
try {
const score = await scoreTrace({
storage,
scorer,
target,
batchId,
datasetId,
datasetItemId: target.datasetItemId,
});
const spanId = score.spanId ?? target.spanId;
if (!spanId) {
throw new Error(`Persisted score is missing spanId for traceId: ${target.traceId}`);
}
return {
ok: true,
index,
traceId: score.traceId ?? target.traceId,
spanId,
...(target.datasetItemId ? { datasetItemId: target.datasetItemId } : {}),
score,
};
} catch (error) {
return {
ok: false,
index,
traceId: target.traceId,
...(target.spanId ? { spanId: target.spanId } : {}),
...(target.datasetItemId ? { datasetItemId: target.datasetItemId } : {}),
error: toBatchResultError(error),View on GitHub (pinned to 75dd419e61)
Solutions
- Always include spanId in the score target: { traceId, spanId } resolved via resolveTargetSpan/root span.
- Check why score.spanId was undefined — ensure the scorer ran with trace/span context (not a bare scorer.run without ids).
- Update custom scorer code to propagate spanId into its returned score.
- Persist traces fully so span resolution succeeds before batch scoring.
- Validate targets before batch scoring to fail fast on missing spanId.
Example fix
// before
const targets = traces.map(t => ({ traceId: t.traceId }));
// after
const targets = traces.map(t => ({ traceId: t.traceId, spanId: t.spans.find(s => s.parentSpanId === null)?.spanId })); Defensive patterns
Strategy: validation
Validate before calling
// require spanId on batch targets up front
targets.forEach(t => {
if (!t.spanId) throw new Error(`Target for trace ${t.traceId} is missing spanId`);
}); Type guard
function hasSpanId(target) {
return typeof target.spanId === 'string' && target.spanId.length > 0;
} Try / catch
try {
const results = await scoreTraceBatchTargets(targets);
} catch (e) {
if (typeof e.message === 'string' && e.message.startsWith('Persisted score is missing spanId')) {
console.error('Scorer dropped span metadata — run scorers with trace/span context');
}
throw e;
} Prevention
- Always build score targets with both traceId and spanId
- Ensure scorers run with trace/span context so results carry spanId
- Propagate spanId in custom scorer result objects
- Validate batch targets before scoring to fail fast
When it happens
Trigger: Batch scoring trace targets where the scorer's run() result has no spanId (scorer invoked without span context) and the target { traceId } was given without spanId — e.g. the trace's span resolution was skipped or the scorer dropped span metadata.
Common situations: Scorer implementations returning custom results that omit spanId; targets built manually with only traceId; traces whose spans failed to resolve earlier but scoring proceeded; custom scorer pipelines bypassing runScorerForTrace's tenancy threading.
Related errors
- Span not found for scoring, traceId: ${trace.traceId}, spanI
- MASTRA_OBSERVABILITY_STORAGE_NOT_AVAILABLE
- Trace not found for scoring, traceId: ${target.traceId}
- OBSERVABILITY_INVALID_CONFIG
- OBSERVABILITY_INVALID_INSTANCE_CONFIG
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/384a998ae7440d18.
Report an issue: GitHub.