{"record":{"id":"67364ad2c7f4336e","repo":"vercel/next.js","slug":"trace-has-no-navigationstart-for-pageurl","errorCode":null,"errorMessage":"Trace has no navigationStart for ${pageUrl}","messagePattern":"Trace has no navigationStart for (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"bench/render-pipeline/client-trace.ts","lineNumber":360,"sourceCode":"    parsedBytes: number\n    fileCount: number\n  }\n): TraceSample {\n  // Trace event arrays are not guaranteed timestamp-ordered (per-thread\n  // buffers flush independently), so sort before any first/last lookup.\n  const sorted = [...events].sort((a, b) => a.ts - b.ts)\n\n  // The main-thread pid/tid pair is identified by the navigationStart\n  // user-timing event for our document; main-thread buckets filter on it\n  // so worker/compositor/browser-process events never pollute the sums.\n  const navStart = sorted.findLast(\n    (event) =>\n      event.name === 'navigationStart' &&\n      event.cat.includes('blink.user_timing') &&\n      event.args?.data?.documentLoaderURL?.startsWith(pageUrl.split('?')[0])\n  )\n  if (!navStart) {\n    throw new Error(`Trace has no navigationStart for ${pageUrl}`)\n  }\n  const { pid, tid, ts: navTs } = navStart\n  // Redirects (e.g. trailingSlash) can make the final document URL differ\n  // from the requested URL; inline-script eval events carry the former.\n  const documentUrl = navStart.args?.data?.documentLoaderURL ?? pageUrl\n\n  const onMain = (event: TraceEvent) =>\n    event.pid === pid && event.tid === tid && event.ts >= navTs\n  const relMs = (ts: number) => (ts - navTs) / 1000\n\n  const firstInstant = (name: string): number | null => {\n    const event = sorted.find((e) => e.name === name && onMain(e))\n    return event ? relMs(event.ts) : null\n  }\n  const lastInstant = (name: string): number | null => {\n    const event = sorted.findLast((e) => e.name === name && onMain(e))\n    return event ? relMs(event.ts) : null\n  }","sourceCodeStart":342,"sourceCodeEnd":378,"githubUrl":"https://github.com/vercel/next.js/blob/0ae8c72462952df163f1b1e0726641bc5b40dc93/bench/render-pipeline/client-trace.ts#L342-L378","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Confirm the page loads without a redirect (check final URL in DevTools) before tracing.","Increase --settle-ms so the trace fully captures post-navigation prefetch processing.","Verify the pageUrl passed to the parser matches the actual navigated document URL.","Re-capture the trace; if it persists, inspect the raw trace JSON for navigationStart events and their documentLoaderURL values."],"exampleFix":"// before: route redirects, final URL differs\n--routes=/docs\n// redirects to /docs/ (trailing slash)\n\n// after: use the final URL\n--routes=/docs/","handlingStrategy":"validation","validationCode":"// Resolve redirects before tracing so pageUrl matches the final document\nasync function finalUrl(url: string): Promise<string> {\n  const res = await fetch(url, { redirect: 'follow' })\n  return res.url\n}\nconst pageUrl = await finalUrl(requestedUrl)","typeGuard":"interface TraceEvent { name: string; cat: string; pid: number; tid: number; ts: number; args?: { data?: { documentLoaderURL?: string } } }\nconst hasNavigationStart = (events: TraceEvent[], pageUrl: string): boolean =>\n  events.some(e => e.name === 'navigationStart' && e.cat.includes('blink.user_timing') && e.args?.data?.documentLoaderURL?.startsWith(pageUrl.split('?')[0]))","tryCatchPattern":"null","preventionTips":["Use the final (post-redirect) URL as the traced page URL.","Ensure --settle-ms is long enough to capture navigation + prefetch processing.","Inspect raw trace JSON for navigationStart events when debugging."],"tags":["trace","chrome-devtools","parsing","performance"],"analyzedSha":"0ae8c72462952df163f1b1e0726641bc5b40dc93","analyzedAt":"2026-08-06T19:44:29.143Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}