{"record":{"id":"12876cec29af5550","repo":"vercel/next.js","slug":"inspect-route-document-contains-next-f-but","errorCode":null,"errorMessage":"[inspect] ${route}: document contains __next_f but the extraction regex matched no inline Flight scripts — the markup shape changed, update the regex in inspectRouteDocument","messagePattern":"\\[inspect\\] (.+?): document contains __next_f but the extraction regex matched no inline Flight scripts — the markup shape changed, update the regex in inspectRouteDocument","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"bench/render-pipeline/benchmark.ts","lineNumber":436,"sourceCode":"    if (!response.ok) {\n      throw new Error(`Request failed (${response.status}) for ${url}`)\n    }\n    const bytes = Buffer.byteLength(text)\n    const gzipBytes = zlib.gzipSync(text).byteLength\n    let inlineFlightBytes = 0\n    let inlineFlightScripts = 0\n    // Inline Flight scripts can carry attributes (e.g. a CSP nonce), so\n    // match any <script ...> tag; the content anchor identifies them.\n    const flightScript = /<script[^>]*>(self\\.__next_f\\.push\\(.*?)<\\/script>/gs\n    for (const match of text.matchAll(flightScript)) {\n      inlineFlightBytes += Buffer.byteLength(match[1])\n      inlineFlightScripts++\n    }\n    if (inlineFlightScripts === 0) {\n      // Every App Router document carries inline Flight scripts; a\n      // silent zero would corrupt the flight-share metric.\n      if (text.includes('__next_f')) {\n        throw new Error(\n          `[inspect] ${route}: document contains __next_f but the extraction regex matched no inline Flight scripts — the markup shape changed, update the regex in inspectRouteDocument`\n        )\n      }\n      throw new Error(\n        `[inspect] ${route}: not an App Router document (no __next_f) — this benchmark only measures App Router routes`\n      )\n    }\n    return {\n      route,\n      bytes,\n      gzipBytes,\n      inlineFlightBytes,\n      inlineFlightShare: bytes > 0 ? inlineFlightBytes / bytes : 0,\n      inlineFlightScripts,\n    }\n  } finally {\n    clearTimeout(timeout)\n  }","sourceCodeStart":418,"sourceCodeEnd":454,"githubUrl":"https://github.com/vercel/next.js/blob/0ae8c72462952df163f1b1e0726641bc5b40dc93/bench/render-pipeline/benchmark.ts#L418-L454","documentation":"Thrown by inspectRouteDocument (benchmark.ts:436) when the document HTML contains the literal '__next_f' (so it looks like an App Router document) but the flight-script extraction regex /<script[^>]*>(self\\.__next_f\\.push\\(.*?)<\\/script>/gs matched zero scripts. The guard exists because a silent zero would corrupt the inlineFlightShare metric; if the markup shape changed (e.g. Flight scripts now use a different tag/attribute/nonce scheme, or __next_f is referenced in non-script context), the regex must be updated rather than reporting wrong numbers.","triggerScenarios":"A Next.js version change alters how inline Flight scripts are emitted: the script tag gains an attribute pattern the regex's [^>]* no longer spans, the push payload format changes, or __next_f appears outside a <script> (e.g. in a data attribute or JSON blob). The check at line 435 (`text.includes('__next_f')`) passes but the matchAll at 428 yields nothing, so line 432-438 fires.","commonSituations":"Upgrading Next.js changes the inline Flight script markup; a CSP nonce or type attribute now wraps the script in a way the regex mishandles; the document references __next_f in a <script type='application/json'> or a data island the regex excludes; Turbopack vs webpack emit differing shapes.","solutions":["Inspect the actual document HTML (curl the route, grep for __next_f) to see the new tag shape.","Update the flightScript regex in inspectRouteDocument (line 427) to match the current markup — e.g. account for new attributes, self-closing variations, or a changed payload delimiter.","Add a fixture test for the regex against a real current document so this breaks loudly in CI next time.","Confirm you're not pointing the benchmark at a non-App-Router route (that case is the separate error at line 440)."],"exampleFix":"// before\nconst flightScript = /<script[^>]*>(self\\.__next_f\\.push\\(.*?)<\\/script>/gs\n\n// after — example: the new markup wraps the script with a nonce AND the push\n// argument is now quoted differently; loosen the tag head and anchor on the push call\nconst flightScript =\n  /<script\\b[^>]*>([\\s\\S]*?self\\.__next_f\\.push\\([\\s\\S]*?<\\/script>/g\n// (adjust to the actual current shape after inspecting the document)","handlingStrategy":"validation","validationCode":"// sanity-check the extraction regex against a current document before relying on it:\nfunction countFlightScripts(html: string): number {\n  const re = /<script[^>]*>(self\\.__next_f\\.push\\(.*?)<\\/script>/gs\n  let n = 0\n  while (re.exec(html)) n++\n  return n\n}\n// in a test: assert countFlightScripts(realCurrentDocument) > 0","typeGuard":"function isFlightRegexStaleError(err: unknown): boolean {\n  return err instanceof Error && /extraction regex matched no inline Flight scripts/.test(err.message)\n}","tryCatchPattern":"// This is a tooling bug, not a runtime blip — don't silently swallow it.\ntry {\n  await inspectRouteDocument(url, route, timeoutMs)\n} catch (err) {\n  if (isFlightRegexStaleError(err)) {\n    console.error('Flight script markup changed. Curl the route, grep __next_f, and update the regex in inspectRouteDocument.')\n  }\n  throw err\n}","preventionTips":["Add a fixture test that runs the regex against a real current App Router document so markup changes break CI loudly.","When upgrading Next.js, re-run the render-pipeline benchmark immediately to catch Flight markup drift.","Curl the failing route and inspect the actual <script> tags before tweaking the regex.","Keep the regex anchored on the semantic invariant (self.__next_f.push) and tolerant of attribute churn."],"tags":["flight-scripts","regex","markup-change","render-pipeline","version-drift","next-js"],"analyzedSha":"0ae8c72462952df163f1b1e0726641bc5b40dc93","analyzedAt":"2026-08-06T19:44:29.143Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}