{"record":{"id":"35492575b57cfc07","repo":"mastra-ai/mastra","slug":"trace-id-is-required-354925","errorCode":null,"errorMessage":"Trace ID is required","messagePattern":"Trace ID is required","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playground-ui/src/domains/traces/hooks/use-trace-spans.ts","lineNumber":27,"sourceCode":"/**\n * Every span of a single trace, with its full payload.\n *\n * The lightweight projection exists to keep blob columns off the read path of a\n * *list*, where the cost is paid once per trace on screen. A trace that is open\n * has already narrowed that to one, and the panel both renders and searches\n * these spans -- `input`, `output` and `attributes` included -- so the\n * projection would only hide content the reader is looking at.\n */\nexport function useTraceSpans(\n  traceId: string | null | undefined,\n): UseQueryResult<{ traceId: string; spans: SearchableSpan[] } | null> {\n  const client = useMastraClient();\n\n  return useQuery({\n    queryKey: ['trace-spans', traceId],\n    queryFn: async () => {\n      if (!traceId) {\n        throw new Error('Trace ID is required');\n      }\n      const res = await client.getTrace(traceId);\n      return res;\n    },\n    // Builds each span's search haystack once per fetch, cached with the query.\n    select: selectSearchableSpans,\n    enabled: !!traceId,\n    staleTime: query => {\n      const data = query.state.data;\n      const isFinished = data?.spans.every(span => Boolean(span.endedAt));\n      return isFinished ? IMMUTABLE_CACHE_TIME : 0;\n    },\n  });\n}\n","sourceCodeStart":9,"sourceCodeEnd":42,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/playground-ui/src/domains/traces/hooks/use-trace-spans.ts#L9-L42","documentation":"useTraceSpans fetches the full trace span tree via client.getTrace(traceId) inside React Query. It throws 'Trace ID is required' when traceId is falsy, converting a missing input into a query error rather than making a malformed request. Callers (traceQuery, traceSpans) inherit this error when they render with no id.","triggerScenarios":"Invoking useTraceSpans(undefined), useTraceSpans(null), or useTraceSpans('') because the trace identifier hasn't resolved at render time (route param pending, selection cleared, async lookup not finished).","commonSituations":"Trace detail view mounted from a stale/deep link with a missing id; a parent renders the spans table while traceId is still being derived from a search-parameter transition; shared component used with an optional traceId prop.","solutions":["Guard the render site: only mount the component/hook consumer when traceId is truthy.","Prefer adding `enabled: !!traceId` to the useQuery call if you can modify the hook.","Check where traceId originates (useParams/useSearchParams/selected row) and ensure a default or early return handles the empty case.","Inspect React Query devtools to confirm the ['trace-spans', traceId] key and reset the query once a valid id appears."],"exampleFix":"// before\nconst spans = useTraceSpans(idFromRoute); // possibly undefined\n// after\nconst spans = useTraceSpans(idFromRoute);\nif (spans.error) return <TraceError missingId={!idFromRoute} />; // or gate render:\n// if (!idFromRoute) return null;","handlingStrategy":"validation","validationCode":"if (typeof traceId !== 'string' || traceId.length === 0) {\n  return <TraceNotSelected />; // never call useTraceSpans without an id\n}\nconst { data } = useTraceSpans(traceId);","typeGuard":"function isTraceId(v: unknown): v is string {\n  return typeof v === 'string' && v.trim().length > 0;\n}","tryCatchPattern":"const q = useTraceSpans(traceId);\nif (q.error) {\n  if (!traceId) return <EmptyState />; // precondition failure, not a server error\n  return <RetryPanel error={q.error} onRetry={q.refetch} />;\n}","preventionTips":["Render trace views only after route/selection state resolves.","Use discriminated state ({state: 'idle'} | {state: 'ready', traceId: string}) to make invalid calls unrepresentable.","Keep query keys and guards in sync when copying this hook pattern.","Handle q.error distinctly from loading before reading q.data."],"tags":["react-query","precondition","traces","playground-ui"],"backgroundTag":"missing-required-parameter","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}