{"record":{"id":"47a5c98324b4d60f","repo":"mastra-ai/mastra","slug":"trace-id-and-span-id-are-required","errorCode":null,"errorMessage":"Trace ID and Span ID are required","messagePattern":"Trace ID and Span ID are required","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/playground-ui/src/domains/traces/hooks/use-span-detail.ts","lineNumber":18,"sourceCode":"import type { LightSpanRecord } from '@mastra/core/storage';\nimport { useMastraClient } from '@mastra/react';\nimport { useQuery } from '@tanstack/react-query';\nimport type { UseQueryResult } from '@tanstack/react-query';\n\nconst IMMUTABLE_CACHE_TIME = 1000 * 60 * 60 * 24 * 30; // 30 days, massive cache, span data is immutable\n\nexport function useSpanDetail(\n  traceId: string | null | undefined,\n  spanId: string | null | undefined,\n): UseQueryResult<{ span: LightSpanRecord & { output?: unknown; result?: unknown } } | null> {\n  const client = useMastraClient();\n\n  return useQuery({\n    queryKey: ['span-detail', traceId, spanId],\n    queryFn: async () => {\n      if (!traceId || !spanId) {\n        throw new Error('Trace ID and Span ID are required');\n      }\n      return client.getSpan(traceId, spanId);\n    },\n    enabled: !!traceId && !!spanId,\n    staleTime: query => {\n      const data = query.state.data;\n\n      if (data?.span?.endedAt) {\n        return IMMUTABLE_CACHE_TIME;\n      }\n\n      return 0;\n    },\n  });\n}\n","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/playground-ui/src/domains/traces/hooks/use-span-detail.ts#L1-L34","documentation":"The useSpanDetail hook's queryFn validates that both traceId and spanId exist before calling client.getSpan, and throws 'Trace ID and Span ID are required' otherwise. The query is normally disabled until both IDs are truthy, so this surfaces when the query runs without valid IDs.","triggerScenarios":"Forcing the ['span-detail'] query to run (refetch/fetchQuery) with missing IDs; invoking the hook and manually enabling/refetching before route params resolve; test code calling spanDetail's queryFn without arguments.","commonSituations":"Span detail panel opened before a span is selected; URL search params not yet hydrated; a refactor renamed the props so undefined IDs are passed through.","solutions":["Gate rendering of the span detail consumer on both IDs being present (the hook's enabled flag already does this for automatic fetching).","Before queryClient.fetchQuery/getQueryData-triggered refetches, assert traceId && spanId.","Fix prop/route plumbing so traceId and spanId are always the resolved values.","Log/inspect the queryKey when it fires to find which ID is undefined."],"exampleFix":"// before\nrefetch(); // traceId not yet set\n// after\nif (traceId && spanId) refetch();","handlingStrategy":"validation","validationCode":"if (!traceId || !spanId) return;\nconst span = await queryClient.fetchQuery({\n  queryKey: ['span-detail', traceId, spanId],\n  queryFn: () => client.getSpan(traceId, spanId),\n});","typeGuard":"const isValidSpanSelection = (v: { traceId?: string; spanId?: string }): v is { traceId: string; spanId: string } =>\n  Boolean(v.traceId) && Boolean(v.spanId);","tryCatchPattern":"try {\n  const span = await client.getSpan(traceId, spanId);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Trace ID and Span ID are required') return null;\n  throw e;\n}","preventionTips":["Render the span detail panel only when both IDs are selected.","Validate URL params before hydrating the hook's arguments.","Keep props typed as required strings and let TypeScript catch undefined at compile time.","In tests, mock route params explicitly instead of relying on defaults."],"tags":["react","react-query","traces","missing-argument","playground-ui"],"backgroundTag":"missing-required-identifier","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}