mastra-ai/mastra · error · Error

Span not found for scoring, traceId: ${trace.traceId}, spanI

Error message

Span not found for scoring, traceId: ${trace.traceId}, spanId: ${spanId ?? 'Not provided'}

What it means

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').

Source

Thrown at packages/core/src/evals/scoreTraces/scoreTracesWorkflow.ts:153

      traceId: string;
      spanId?: string;
      datasetItemId?: string;
      error: Error;
    };

type ScoreTraceReferenceTarget = { traceId: string; spanId?: string };

function isScoreTraceReferenceTarget(target: ScoreTraceTarget): target is ScoreTraceReferenceTarget {
  return 'traceId' in target;
}

function resolveTargetSpan({ trace, spanId }: { trace: TraceRecord; spanId?: string }): SpanRecord {
  const span = spanId
    ? trace.spans.find(candidateSpan => candidateSpan.spanId === spanId)
    : trace.spans.find(candidateSpan => candidateSpan.parentSpanId === null);

  if (!span) {
    throw new Error(`Span not found for scoring, traceId: ${trace.traceId}, spanId: ${spanId ?? 'Not provided'}`);
  }

  return span;
}

/** Resolve the target span for a trace/target pair. */
async function resolveTraceAndSpan({
  storage,
  target,
}: {
  storage: MastraStorage;
  target: ScoreTraceTarget;
}): Promise<{ trace: TraceRecord; span: SpanRecord }> {
  if (!isScoreTraceReferenceTarget(target)) {
    return {
      trace: target.trace,
      span: resolveTargetSpan({ trace: target.trace, spanId: target.spanId }),
    };

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Log/inspect trace.spans and confirm the exact spanId you pass exists in that trace.
  2. If you don't need a specific span, omit spanId so the root span is used — but ensure a root span was persisted.
  3. Re-fetch the trace (observabilityStore.getTrace) just before scoring rather than caching old ids.
  4. Check your trace exporter/sampler isn't dropping the root span.
  5. Verify spans are actually being persisted to storage (storage config, sampling config).

Example fix

// before
await scorerWorkflow.score({ target: { traceId, spanId: 'stale-id' } });
// after: resolve span id from a fresh trace fetch
const trace = await observabilityStore.getTrace({ traceId });
const spanId = trace.spans.find(s => s.parentSpanId === null)?.spanId;
await scorerWorkflow.score({ target: { traceId, spanId } });
Defensive patterns

Strategy: validation

Validate before calling

// resolve and confirm the span before invoking scoring
const trace = await observabilityStore.getTrace({ traceId });
const span = spanId
  ? trace?.spans.find(s => s.spanId === spanId)
  : trace?.spans.find(s => s.parentSpanId === null);
if (!span) throw new Error(`Refusing to score: span ${spanId ?? '(root)'} missing in trace ${traceId}`);

Type guard

function spanExistsInTrace(trace, spanId) {
  if (!trace?.spans?.length) return false;
  return spanId
    ? trace.spans.some(s => s.spanId === spanId)
    : trace.spans.some(s => s.parentSpanId === null);
}

Try / catch

try {
  await scoreTraces({ target: { traceId, spanId } });
} catch (e) {
  if (typeof e.message === 'string' && e.message.startsWith('Span not found for scoring')) {
    const trace = await observabilityStore.getTrace({ traceId });
    const root = trace.spans.find(s => s.parentSpanId === null);
    return scoreTraces({ target: { traceId, spanId: root.spanId } });
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/7d52eff79f18143e. Report an issue: GitHub.