{"record":{"id":"64bc68260bda1ec7","repo":"mastra-ai/mastra","slug":"trace-must-have-a-spans-array","errorCode":null,"errorMessage":"Trace must have a spans array","messagePattern":"Trace must have a spans array","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/evals/scoreTraces/utils.ts","lineNumber":221,"sourceCode":"    toolCallId: toolSpan.spanId,\n    toolName: toolSpan.entityName ?? toolSpan.entityId ?? 'unknown',\n    toolId: toolSpan.entityId,\n    args: toolSpan.input || {},\n    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 */","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/evals/scoreTraces/utils.ts#L203-L239","documentation":"validateTrace throws this when `trace.spans` is missing or not an array. A TraceRecord without a valid spans array cannot be traversed to build the span tree used for extracting scorer input/output.","triggerScenarios":"A trace record fetched from storage has no spans field (e.g. only metadata was persisted, or a hand-constructed/malformed TraceRecord object is passed to the transformation helpers).","commonSituations":"Partially ingested traces; custom storage adapters that serialize traces incorrectly (dropping spans); passing an object of the wrong shape (TS unchecked, e.g. from JSON) into the scoring pipeline.","solutions":["Verify the trace was fully persisted (spans included) in the observability storage before scoring","Re-check the storage adapter's trace serialization/deserialization to ensure spans survive round-trips","Validate the record shape (Array.isArray(trace.spans)) before calling the transformation"],"exampleFix":"// before\ntransformTraceToScorerInputAndOutput(maybeTrace);\n// after\nif (!maybeTrace || !Array.isArray(maybeTrace.spans)) throw new Error('Invalid trace record');\ntransformTraceToScorerInputAndOutput(maybeTrace);","handlingStrategy":"validation","validationCode":"if (!trace || !Array.isArray(trace.spans)) {\n  throw new Error('Trace record is malformed: spans array missing');\n}","typeGuard":"function hasSpansArray(t: unknown): t is TraceRecord & { spans: unknown[] } {\n  return typeof t === 'object' && t !== null && Array.isArray((t as TraceRecord).spans);\n}","tryCatchPattern":"try {\n  transformTraceToScorerInputAndOutput(trace);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Trace must have a spans array') {\n    logger.warn('Malformed trace record; skipping scoring', { traceId: trace?.traceId });\n  } else throw e;\n}","preventionTips":["Validate deserialized trace records against the TraceRecord shape","Verify custom storage adapters serialize spans correctly","Only pass records obtained from the observability store into scoring helpers","Add schema validation at ingestion boundaries"],"tags":["trace","shape-validation","scoring"],"backgroundTag":"schema-validation-failed","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}