{"record":{"id":"9954099f5d8de1b3","repo":"mastra-ai/mastra","slug":"trace-is-null-or-undefined","errorCode":null,"errorMessage":"Trace is null or undefined","messagePattern":"Trace is null or undefined","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/evals/scoreTraces/utils.ts","lineNumber":217,"sourceCode":"function reconstructToolInvocations(spanTree: SpanTree, parentSpanId: string) {\n  const toolSpans = getChildrenOfType<SpanRecord>(spanTree, parentSpanId, SpanType.TOOL_CALL);\n\n  return toolSpans.map(toolSpan => ({\n    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}","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/evals/scoreTraces/utils.ts#L199-L235","documentation":"validateTrace in the score-traces utils throws this plain Error when the trace record passed for scorer transformation is null or undefined. It is a precondition check ensuring downstream span-tree building never operates on a missing trace.","triggerScenarios":"prepareTraceForTransformation receiving a null/undefined TraceRecord — e.g. storage.getTrace / trace lookup returned nothing for the requested traceId and the result was passed through unchecked.","commonSituations":"Scoring a traceId that does not exist (wrong ID, wrong storage backend, data pruned by retention); async trace lookup racing with ingestion so the record is not yet persisted.","solutions":["Check the trace lookup result for null/undefined before invoking the scorer transformation","Verify the traceId exists in the configured storage (query the observability store first)","Ensure the trace has finished and been persisted before triggering the scoring workflow"],"exampleFix":"// before\nconst input = transformTraceToScorerInputAndOutput(trace);\n// after\nif (!trace) return; // or fetch/await the trace first\nconst input = transformTraceToScorerInputAndOutput(trace);","handlingStrategy":"type-guard","validationCode":"const trace = await storage.getStore('observability')?.getTrace({ traceId });\nif (!trace) throw new Error(`Trace ${traceId} not found`);","typeGuard":"function isTraceRecord(t: TraceRecord | null | undefined): t is TraceRecord {\n  return t != null && typeof t === 'object' && Array.isArray((t as TraceRecord).spans);\n}","tryCatchPattern":"try {\n  transformTraceToScorerInputAndOutput(trace);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Trace is null or undefined') {\n    logger.warn('Skipping scoring: trace missing', { traceId });\n  } else throw e;\n}","preventionTips":["Always null-check trace lookups before scoring","Confirm the traceId exists in the active storage backend","Wait for trace persistence before triggering scorers","Account for retention policies deleting traces"],"tags":["trace","null-check","scoring"],"backgroundTag":"null-or-undefined-trace","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}