mastra-ai/mastra · warning · Error

traceId and spanId are required

Error message

traceId and spanId are required

What it means

React Query queryFn for the branch query in the playground UI requires both traceId and spanId to fetch a span's branch, and throws this error when either is missing. In practice the query is disabled (enabled: !!traceId && !!spanId) so this only fires if the query is forced to run with undefined IDs.

Source

Thrown at packages/playground-ui/src/domains/traces/hooks/use-branch.ts:26

export interface UseBranchArgs {
  traceId: string | null | undefined;
  spanId: string | null | undefined;
  depth?: number;
}

export function useBranch({
  traceId,
  spanId,
  depth,
}: UseBranchArgs): UseQueryResult<{ traceId: string; spans: SearchableSpan[] } | null> {
  const client = useMastraClient();

  return useQuery({
    queryKey: ['branch', traceId, spanId, depth],
    queryFn: async () => {
      if (!traceId || !spanId) {
        throw new Error('traceId and spanId are required');
      }
      return client.getBranch({ traceId, spanId, depth });
    },
    // Builds each span's search haystack once per fetch, cached with the query.
    select: selectSearchableSpans,
    enabled: !!traceId && !!spanId,
    staleTime: query => {
      const data = query.state.data;
      const isFinished = data?.spans.every(s => Boolean(s.endedAt));
      return isFinished ? IMMUTABLE_CACHE_TIME : 0;
    },
  });
}

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Wait for traceId/spanId to be defined before mounting/refetching (the hook already disables the query when either is falsy).
  2. If using queryClient.fetchQuery manually, check both IDs before invoking.
  3. Fix URL/route parsing so trace and span IDs are extracted before the hook runs.
  4. Render the branch view only after the parent trace/span selection resolves (conditional rendering).

Example fix

// before
const { data } = useBranch(undefined, spanId);
// after
const { data } = traceId && spanId ? useBranch(traceId, spanId) : { data: undefined };
Defensive patterns

Strategy: validation

Validate before calling

if (!traceId || !spanId) return null; // skip branch fetch until both IDs exist
const branch = await queryClient.fetchQuery({
  queryKey: ['branch', traceId, spanId, depth],
  queryFn: () => client.getBranch({ traceId, spanId, depth }),
});

Type guard

const hasTraceSpan = (v: { traceId?: string; spanId?: string }): v is { traceId: string; spanId: string } =>
  typeof v.traceId === 'string' && v.traceId.length > 0 && typeof v.spanId === 'string' && v.spanId.length > 0;

Try / catch

try {
  const data = await queryClient.fetchQuery({ queryKey: ['branch', traceId, spanId, depth], queryFn });
} catch (e) {
  if (e instanceof Error && e.message === 'traceId and spanId are required') return null;
  throw e;
}

Prevention

When it happens

Trigger: Manually triggering/refetching the ['branch'] query with undefined traceId or spanId; rendering a component that calls useBranch before IDs resolve and forcing an immediate refetch; calling branchQuery directly in tests without arguments.

Common situations: Deep-linking to a span detail view where URL params are not yet parsed; trace data still loading so IDs are undefined; custom queryClient.fetchQuery calls that skip the enabled guard.

Related errors


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