mastra-ai/mastra · error · Error
Trace is null or undefined
Error message
Trace is null or undefined
What it means
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.
Source
Thrown at packages/core/src/evals/scoreTraces/utils.ts:217
function reconstructToolInvocations(spanTree: SpanTree, parentSpanId: string) {
const toolSpans = getChildrenOfType<SpanRecord>(spanTree, parentSpanId, SpanType.TOOL_CALL);
return toolSpans.map(toolSpan => ({
toolCallId: toolSpan.spanId,
toolName: toolSpan.entityName ?? toolSpan.entityId ?? 'unknown',
toolId: toolSpan.entityId,
args: toolSpan.input || {},
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}`);
}
}
}View on GitHub (pinned to 75dd419e61)
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
Example fix
// before const input = transformTraceToScorerInputAndOutput(trace); // after if (!trace) return; // or fetch/await the trace first const input = transformTraceToScorerInputAndOutput(trace);
Defensive patterns
Strategy: type-guard
Validate before calling
const trace = await storage.getStore('observability')?.getTrace({ traceId });
if (!trace) throw new Error(`Trace ${traceId} not found`); Type guard
function isTraceRecord(t: TraceRecord | null | undefined): t is TraceRecord {
return t != null && typeof t === 'object' && Array.isArray((t as TraceRecord).spans);
} Try / catch
try {
transformTraceToScorerInputAndOutput(trace);
} catch (e) {
if (e instanceof Error && e.message === 'Trace is null or undefined') {
logger.warn('Skipping scoring: trace missing', { traceId });
} else throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Trace must have a spans array
- Trace has no spans
- No model generation span found in trace
- Root agent span has no output
- Factory rules must be an object.
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/9954099f5d8de1b3.
Report an issue: GitHub.