{"record":{"id":"7aca44e0b11fb75f","repo":"mastra-ai/mastra","slug":"trace-has-no-spans","errorCode":null,"errorMessage":"Trace has no spans","messagePattern":"Trace has no spans","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/evals/scoreTraces/utils.ts","lineNumber":225,"sourceCode":"    result: toolSpan.output || {},\n    state: 'result' as const,\n  }));\n}\n\n/**\n * Validate trace structure and throw descriptive errors\n */\nexport function validateTrace(trace: TraceRecord): void {\n  if (!trace) {\n    throw new Error('Trace is null or undefined');\n  }\n\n  if (!trace.spans || !Array.isArray(trace.spans)) {\n    throw new Error('Trace must have a spans array');\n  }\n\n  if (trace.spans.length === 0) {\n    throw new Error('Trace has no spans');\n  }\n\n  // Check for circular references in parent-child relationships\n  const spanIds = new Set(trace.spans.map(span => span.spanId));\n  for (const span of trace.spans) {\n    if (span.parentSpanId && !spanIds.has(span.parentSpanId)) {\n      throw new Error(`Span ${span.spanId} references non-existent parent ${span.parentSpanId}`);\n    }\n  }\n}\n\n/**\n * Find the most recent model span that contains conversation history\n */\nfunction findPrimaryLLMSpan(spanTree: SpanTree, rootAgentSpan: SpanRecord): SpanRecord {\n  const directLLMSpans = getChildrenOfType<SpanRecord>(spanTree, rootAgentSpan.spanId, SpanType.MODEL_GENERATION);\n  if (directLLMSpans.length > 0) {\n    // There should only be one model generation span per agent run which is a direct child of the root agent span","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/evals/scoreTraces/utils.ts#L207-L243","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Confirm spans were actually persisted for the run (inspect the observability store/trace in Studio)","Re-run the agent generation to produce a fresh trace with spans","Skip scoring for empty traces rather than routing them to the transformation"],"exampleFix":"// before\nconst result = scoreTrace({ trace: storedTrace });\n// after\nif (!storedTrace.spans.length) skipScoring(storedTrace.traceId);\nelse scoreTrace({ trace: storedTrace });","handlingStrategy":"validation","validationCode":"if (Array.isArray(trace?.spans) && trace.spans.length === 0) {\n  throw new Error(`Trace ${trace.traceId} has no spans; cannot score`);\n}","typeGuard":"function isNonEmptyTrace(t: TraceRecord | null): t is TraceRecord & { spans: [SpanRecord, ...SpanRecord[]] } {\n  return !!t && Array.isArray(t.spans) && t.spans.length > 0;\n}","tryCatchPattern":"try {\n  await scoreTrace({ trace });\n} catch (e) {\n  if (e instanceof Error && e.message === 'Trace has no spans') {\n    logger.warn('Empty trace; skipping score', { traceId: trace?.traceId });\n  } else throw e;\n}","preventionTips":["Skip scoring for empty traces instead of routing them to the pipeline","Investigate ingestion failures if traces persist with zero spans","Check retention/cleanup jobs for span deletion","Re-run failed generations to produce fresh traces"],"tags":["trace","empty-data","scoring"],"backgroundTag":"empty-trace-spans","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}