mastra-ai/mastra · error · MastraError

OBSERVABILITY_STORAGE_GET_ROOT_SPAN_NOT_IMPLEMENTED

OBSERVABILITY_STORAGE_GET_ROOT_SPAN_NOT_IMPLEMENTED

Error message

This storage provider does not support getting root spans

What it means

getRootSpan() in the ObservabilityStorage base class throws by default; it is only available on adapters that override it. Hitting this error means the configured storage cannot resolve a single root span by id.

Source

Thrown at packages/core/src/storage/domains/observability/base.ts:202

  }

  /**
   * Retrieves a single span.
   */
  async getSpan(_args: GetSpanArgs): Promise<GetSpanResponse | null> {
    throw new MastraError({
      id: 'OBSERVABILITY_STORAGE_GET_SPAN_NOT_IMPLEMENTED',
      domain: ErrorDomain.MASTRA_OBSERVABILITY,
      category: ErrorCategory.SYSTEM,
      text: 'This storage provider does not support getting spans',
    });
  }

  /**
   * Retrieves a single root span.
   */
  async getRootSpan(_args: GetRootSpanArgs): Promise<GetRootSpanResponse | null> {
    throw new MastraError({
      id: 'OBSERVABILITY_STORAGE_GET_ROOT_SPAN_NOT_IMPLEMENTED',
      domain: ErrorDomain.MASTRA_OBSERVABILITY,
      category: ErrorCategory.SYSTEM,
      text: 'This storage provider does not support getting root spans',
    });
  }

  /**
   * Retrieves a single trace with all its associated spans.
   */
  async getTrace(_args: GetTraceArgs): Promise<GetTraceResponse | null> {
    throw new MastraError({
      id: 'OBSERVABILITY_STORAGE_GET_TRACE_NOT_IMPLEMENTED',
      domain: ErrorDomain.MASTRA_OBSERVABILITY,
      category: ErrorCategory.SYSTEM,
      text: 'This storage provider does not support getting traces',
    });
  }

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Use a storage adapter that implements the observability read domain (overrides getRootSpan).
  2. Fetch the full trace with getTrace() and derive the root span (span with no parentId) client-side.
  3. Override getRootSpan() in your adapter (SELECT ... WHERE spanId = ? AND parentId IS NULL, or lookup the trace and filter).
  4. Guard with a capability check and fall back to getTrace-based resolution.

Example fix

// before
const root = await observability.getRootSpan({ spanId });

// after (fallback)
const trace = await observability.getTrace({ traceId: span.traceId });
const root = trace?.spans.find(s => !s.parentSpanId) ?? null;
Defensive patterns

Strategy: fallback

Validate before calling

const supportsRootSpan = obs.getRootSpan !== ObservabilityStorage.prototype.getRootSpan;

Type guard

function supportsGetRootSpan(o: { getRootSpan: unknown }): boolean {
  return o.getRootSpan !== (ObservabilityStorage.prototype as any).getRootSpan;
}

Try / catch

try {
  return await obs.getRootSpan(args);
} catch (e) {
  if ((e as MastraError).id === 'OBSERVABILITY_STORAGE_GET_ROOT_SPAN_NOT_IMPLEMENTED') {
    const trace = await obs.getTrace(args).catch(() => null);
    return trace?.spans.find(s => !s.parentSpanId) ?? null;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling await storage.getObservability().getRootSpan(args) on a backend that does not override the method — typically while resolving the top-level span of a trace for UI drill-down.

Common situations: Custom storage adapter implementing only write-side observability APIs; legacy adapter versions predating the root-span read API; pointing playground/agent traces UI at unsupported storage.

Related errors


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