vercel/next.js · error

Trace has no navigationStart for ${pageUrl}

Error message

Trace has no navigationStart for ${pageUrl}

What it means

Thrown while parsing a Chrome DevTools Protocol performance trace when no event named navigationStart in the blink.user_timing category with a documentLoaderURL matching the traced page URL is found. The navigationStart event anchors all main-thread timing (its pid/tid/ts define the zero point and the main thread), so its absence makes every downstream metric undefined. Trace event buffers flush per-thread out of order, so the parser sorts first — if it still cannot find the anchor, the trace is unusable for this page.

Source

Thrown at bench/render-pipeline/client-trace.ts:360

    parsedBytes: number
    fileCount: number
  }
): TraceSample {
  // Trace event arrays are not guaranteed timestamp-ordered (per-thread
  // buffers flush independently), so sort before any first/last lookup.
  const sorted = [...events].sort((a, b) => a.ts - b.ts)

  // The main-thread pid/tid pair is identified by the navigationStart
  // user-timing event for our document; main-thread buckets filter on it
  // so worker/compositor/browser-process events never pollute the sums.
  const navStart = sorted.findLast(
    (event) =>
      event.name === 'navigationStart' &&
      event.cat.includes('blink.user_timing') &&
      event.args?.data?.documentLoaderURL?.startsWith(pageUrl.split('?')[0])
  )
  if (!navStart) {
    throw new Error(`Trace has no navigationStart for ${pageUrl}`)
  }
  const { pid, tid, ts: navTs } = navStart
  // Redirects (e.g. trailingSlash) can make the final document URL differ
  // from the requested URL; inline-script eval events carry the former.
  const documentUrl = navStart.args?.data?.documentLoaderURL ?? pageUrl

  const onMain = (event: TraceEvent) =>
    event.pid === pid && event.tid === tid && event.ts >= navTs
  const relMs = (ts: number) => (ts - navTs) / 1000

  const firstInstant = (name: string): number | null => {
    const event = sorted.find((e) => e.name === name && onMain(e))
    return event ? relMs(event.ts) : null
  }
  const lastInstant = (name: string): number | null => {
    const event = sorted.findLast((e) => e.name === name && onMain(e))
    return event ? relMs(event.ts) : null
  }

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Confirm the page loads without a redirect (check final URL in DevTools) before tracing.
  2. Increase --settle-ms so the trace fully captures post-navigation prefetch processing.
  3. Verify the pageUrl passed to the parser matches the actual navigated document URL.
  4. Re-capture the trace; if it persists, inspect the raw trace JSON for navigationStart events and their documentLoaderURL values.

Example fix

// before: route redirects, final URL differs
--routes=/docs
// redirects to /docs/ (trailing slash)

// after: use the final URL
--routes=/docs/
Defensive patterns

Strategy: validation

Validate before calling

// Resolve redirects before tracing so pageUrl matches the final document
async function finalUrl(url: string): Promise<string> {
  const res = await fetch(url, { redirect: 'follow' })
  return res.url
}
const pageUrl = await finalUrl(requestedUrl)

Type guard

interface TraceEvent { name: string; cat: string; pid: number; tid: number; ts: number; args?: { data?: { documentLoaderURL?: string } } }
const hasNavigationStart = (events: TraceEvent[], pageUrl: string): boolean =>
  events.some(e => e.name === 'navigationStart' && e.cat.includes('blink.user_timing') && e.args?.data?.documentLoaderURL?.startsWith(pageUrl.split('?')[0]))

Try / catch

null

Prevention

When it happens

Trigger: The trace was captured against a different page than expected; the navigation was a redirect so documentLoaderURL differs; the trace started after navigation; Chrome dropped the user-timing event; the page crashed before navigationStart fired; querying with a pageUrl whose path/query does not match documentLoaderURL.

Common situations: Trailing-slash redirects change the final URL; the traced route redirected to another; settle-ms too short so the trace was stopped early; a mismatch between requested URL and resolved document URL (e.g. locale prefix).

Related errors


AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06). Data as JSON: /api/errors/67364ad2c7f4336e. Report an issue: GitHub.