mastra-ai/mastra · error · Error

Trace has no spans

Error message

Trace has no spans

What it means

validateTrace throws this when `trace.spans` is an empty array. Scoring requires at least one span (notably a root agent_run span) to derive scorer input/output.

Source

Thrown at packages/core/src/evals/scoreTraces/utils.ts:225

    result: toolSpan.output || {},
    state: 'result' as const,
  }));
}

/**
 * Validate trace structure and throw descriptive errors
 */
export function validateTrace(trace: TraceRecord): void {
  if (!trace) {
    throw new Error('Trace is null or undefined');
  }

  if (!trace.spans || !Array.isArray(trace.spans)) {
    throw new Error('Trace must have a spans array');
  }

  if (trace.spans.length === 0) {
    throw new Error('Trace has no spans');
  }

  // Check for circular references in parent-child relationships
  const spanIds = new Set(trace.spans.map(span => span.spanId));
  for (const span of trace.spans) {
    if (span.parentSpanId && !spanIds.has(span.parentSpanId)) {
      throw new Error(`Span ${span.spanId} references non-existent parent ${span.parentSpanId}`);
    }
  }
}

/**
 * Find the most recent model span that contains conversation history
 */
function findPrimaryLLMSpan(spanTree: SpanTree, rootAgentSpan: SpanRecord): SpanRecord {
  const directLLMSpans = getChildrenOfType<SpanRecord>(spanTree, rootAgentSpan.spanId, SpanType.MODEL_GENERATION);
  if (directLLMSpans.length > 0) {
    // There should only be one model generation span per agent run which is a direct child of the root agent span

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Confirm spans were actually persisted for the run (inspect the observability store/trace in Studio)
  2. Re-run the agent generation to produce a fresh trace with spans
  3. Skip scoring for empty traces rather than routing them to the transformation

Example fix

// before
const result = scoreTrace({ trace: storedTrace });
// after
if (!storedTrace.spans.length) skipScoring(storedTrace.traceId);
else scoreTrace({ trace: storedTrace });
Defensive patterns

Strategy: validation

Validate before calling

if (Array.isArray(trace?.spans) && trace.spans.length === 0) {
  throw new Error(`Trace ${trace.traceId} has no spans; cannot score`);
}

Type guard

function isNonEmptyTrace(t: TraceRecord | null): t is TraceRecord & { spans: [SpanRecord, ...SpanRecord[]] } {
  return !!t && Array.isArray(t.spans) && t.spans.length > 0;
}

Try / catch

try {
  await scoreTrace({ trace });
} catch (e) {
  if (e instanceof Error && e.message === 'Trace has no spans') {
    logger.warn('Empty trace; skipping score', { traceId: trace?.traceId });
  } else throw e;
}

Prevention

When it happens

Trigger: A trace record exists but its spans array is empty — e.g. all spans were deleted by retention/cleanup, ingestion failed before any span was written, or the trace was created but the agent run never emitted spans.

Common situations: Storage retention pruning spans but keeping the trace row; failed/crashed run with a persisted empty trace; filtering spans out upstream before calling the scorer helpers.

Related errors


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