{"record":{"id":"7d52eff79f18143e","repo":"mastra-ai/mastra","slug":"span-not-found-for-scoring-traceid-trace-trace","errorCode":null,"errorMessage":"Span not found for scoring, traceId: ${trace.traceId}, spanId: ${spanId ?? 'Not provided'}","messagePattern":"Span not found for scoring, traceId: (.+?), spanId: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/evals/scoreTraces/scoreTracesWorkflow.ts","lineNumber":153,"sourceCode":"      traceId: string;\n      spanId?: string;\n      datasetItemId?: string;\n      error: Error;\n    };\n\ntype ScoreTraceReferenceTarget = { traceId: string; spanId?: string };\n\nfunction isScoreTraceReferenceTarget(target: ScoreTraceTarget): target is ScoreTraceReferenceTarget {\n  return 'traceId' in target;\n}\n\nfunction resolveTargetSpan({ trace, spanId }: { trace: TraceRecord; spanId?: string }): SpanRecord {\n  const span = spanId\n    ? trace.spans.find(candidateSpan => candidateSpan.spanId === spanId)\n    : trace.spans.find(candidateSpan => candidateSpan.parentSpanId === null);\n\n  if (!span) {\n    throw new Error(`Span not found for scoring, traceId: ${trace.traceId}, spanId: ${spanId ?? 'Not provided'}`);\n  }\n\n  return span;\n}\n\n/** Resolve the target span for a trace/target pair. */\nasync function resolveTraceAndSpan({\n  storage,\n  target,\n}: {\n  storage: MastraStorage;\n  target: ScoreTraceTarget;\n}): Promise<{ trace: TraceRecord; span: SpanRecord }> {\n  if (!isScoreTraceReferenceTarget(target)) {\n    return {\n      trace: target.trace,\n      span: resolveTargetSpan({ trace: target.trace, spanId: target.spanId }),\n    };","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/evals/scoreTraces/scoreTracesWorkflow.ts#L135-L171","documentation":"resolveTargetSpan in scoreTracesWorkflow.ts looks up the span to score within a TraceRecord: by explicit spanId if given, otherwise the first root span (parentSpanId === null). If no span matches, it throws this plain Error including the traceId and the requested spanId (or 'Not provided').","triggerScenarios":"Calling scoreTraces / the score-traces workflow with a target { traceId, spanId } where spanId doesn't exist in the stored trace, or omitting spanId when the trace has no root span (parentSpanId === null) — e.g. all spans are children or the trace record is truncated.","commonSituations":"Stale spanId after re-running/re-tracing; trace sampling or exporter dropping spans so the root never persisted; passing a spanId from a different trace; observability storage retention pruning spans; traces loaded from a storage backend that stores only child spans.","solutions":["Log/inspect trace.spans and confirm the exact spanId you pass exists in that trace.","If you don't need a specific span, omit spanId so the root span is used — but ensure a root span was persisted.","Re-fetch the trace (observabilityStore.getTrace) just before scoring rather than caching old ids.","Check your trace exporter/sampler isn't dropping the root span.","Verify spans are actually being persisted to storage (storage config, sampling config)."],"exampleFix":"// before\nawait scorerWorkflow.score({ target: { traceId, spanId: 'stale-id' } });\n// after: resolve span id from a fresh trace fetch\nconst trace = await observabilityStore.getTrace({ traceId });\nconst spanId = trace.spans.find(s => s.parentSpanId === null)?.spanId;\nawait scorerWorkflow.score({ target: { traceId, spanId } });","handlingStrategy":"validation","validationCode":"// resolve and confirm the span before invoking scoring\nconst trace = await observabilityStore.getTrace({ traceId });\nconst span = spanId\n  ? trace?.spans.find(s => s.spanId === spanId)\n  : trace?.spans.find(s => s.parentSpanId === null);\nif (!span) throw new Error(`Refusing to score: span ${spanId ?? '(root)'} missing in trace ${traceId}`);","typeGuard":"function spanExistsInTrace(trace, spanId) {\n  if (!trace?.spans?.length) return false;\n  return spanId\n    ? trace.spans.some(s => s.spanId === spanId)\n    : trace.spans.some(s => s.parentSpanId === null);\n}","tryCatchPattern":"try {\n  await scoreTraces({ target: { traceId, spanId } });\n} catch (e) {\n  if (typeof e.message === 'string' && e.message.startsWith('Span not found for scoring')) {\n    const trace = await observabilityStore.getTrace({ traceId });\n    const root = trace.spans.find(s => s.parentSpanId === null);\n    return scoreTraces({ target: { traceId, spanId: root.spanId } });\n  }\n  throw e;\n}","preventionTips":["Fetch traceId/spanId from the run result at scoring time, never from cached ids","Confirm root spans persist (check sampler/exporter config)","Verify spanIds against the trace record before scoring","Watch for retention windows expiring spans"],"tags":["observability","tracing","score-traces","span-lookup"],"backgroundTag":"span-not-found","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}