{"record":{"id":"6d00ae4ba90f4504","repo":"mastra-ai/mastra","slug":"observability-storage-get-spans-not-implemented","errorCode":"OBSERVABILITY_STORAGE_GET_SPANS_NOT_IMPLEMENTED","errorMessage":"This storage provider does not support batch-fetching spans","messagePattern":"This storage provider does not support batch-fetching spans","errorType":"error_code","errorClass":"MastraError","httpStatus":null,"severity":"error","filePath":"packages/core/src/storage/domains/observability/base.ts","lineNumber":310,"sourceCode":"      if (!isFallbackTrigger) throw error;\n    }\n\n    // Fallback: pull the whole trace, walk in memory.\n    const trace = await this.getTrace({ traceId: parsed.traceId });\n    if (!trace) return null;\n    const spans = extractBranchSpans(trace.spans, parsed.spanId, parsed.depth);\n    if (spans.length === 0) return null;\n    return { traceId: parsed.traceId, spans };\n  }\n\n  /**\n   * Batch-fetches spans by spanId within a single trace. Used by the\n   * optimized {@link getBranch} path to fetch only the spans that belong to\n   * the requested branch (after walking the lightweight structure to identify\n   * them) instead of pulling the entire trace.\n   */\n  async getSpans(_args: GetSpansArgs): Promise<GetSpansResponse> {\n    throw new MastraError({\n      id: 'OBSERVABILITY_STORAGE_GET_SPANS_NOT_IMPLEMENTED',\n      domain: ErrorDomain.MASTRA_OBSERVABILITY,\n      category: ErrorCategory.SYSTEM,\n      text: 'This storage provider does not support batch-fetching spans',\n    });\n  }\n\n  /**\n   * Retrieves a list of traces with optional filtering.\n   */\n  async listTraces(_args: ListTracesArgs): Promise<ListTracesResponse> {\n    throw new MastraError({\n      id: 'OBSERVABILITY_STORAGE_LIST_TRACES_NOT_IMPLEMENTED',\n      domain: ErrorDomain.MASTRA_OBSERVABILITY,\n      category: ErrorCategory.SYSTEM,\n      text: 'This storage provider does not support listing traces',\n    });\n  }","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/storage/domains/observability/base.ts#L292-L328","documentation":"getSpans() batch-fetches spans by spanId within a single trace; it powers the optimized getBranch() path. The base class default throws, so hitting this error means the storage adapter lacks the batch span-fetch capability needed for branch expansion.","triggerScenarios":"Calling getSpans({ traceId, spanIds }) directly, or calling getBranch() on an adapter that resolves branches via the lightweight structure + getSpans fast path but did not override getSpans.","commonSituations":"Custom adapters implementing getStructure but not the batched fetch (getBranch then falls through); minimal storage backends in tests; adapters predating the optimized getBranch implementation.","solutions":["Override getSpans() in your adapter (SELECT ... WHERE traceId = ? AND spanId IN (...)).","Use getTrace() to fetch all spans of the trace and filter by the requested span ids client-side.","Avoid the getBranch fast path by relying on adapters that implement the full read domain.","Capability-check getSpans before invoking getBranch and choose the full-trace fallback."],"exampleFix":"// before\nconst spans = await observability.getSpans({ traceId, spanIds });\n\n// after (fallback)\nconst trace = await observability.getTrace({ traceId });\nconst spans = trace?.spans.filter(s => spanIds.includes(s.spanId)) ?? [];","handlingStrategy":"fallback","validationCode":"const supportsGetSpans = obs.getSpans !== ObservabilityStorage.prototype.getSpans;","typeGuard":"function supportsBatchSpanFetch(o: { getSpans: unknown }): boolean {\n  return o.getSpans !== (ObservabilityStorage.prototype as any).getSpans;\n}","tryCatchPattern":"try {\n  return await obs.getSpans({ traceId, spanIds });\n} catch (e) {\n  if ((e as MastraError).id === 'OBSERVABILITY_STORAGE_GET_SPANS_NOT_IMPLEMENTED') {\n    const trace = await obs.getTrace({ traceId }).catch(() => null);\n    return trace?.spans.filter(s => spanIds.includes(s.spanId)) ?? [];\n  }\n  throw e;\n}","preventionTips":["Implement getSpans in custom adapters so getBranch's optimized path works.","Keep a full-trace fallback for backends without batch fetch.","Test getBranch against your real adapter, not an in-memory double."],"tags":["storage","observability","tracing","batch","unsupported-operation"],"backgroundTag":"storage-provider-not-implemented","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}