vercel/next.js · error
[inspect] ${route}: document contains __next_f but the extra
Error message
[inspect] ${route}: document contains __next_f but the extraction regex matched no inline Flight scripts — the markup shape changed, update the regex in inspectRouteDocument What it means
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.
Source
Thrown at bench/render-pipeline/benchmark.ts:436
if (!response.ok) {
throw new Error(`Request failed (${response.status}) for ${url}`)
}
const bytes = Buffer.byteLength(text)
const gzipBytes = zlib.gzipSync(text).byteLength
let inlineFlightBytes = 0
let inlineFlightScripts = 0
// Inline Flight scripts can carry attributes (e.g. a CSP nonce), so
// match any <script ...> tag; the content anchor identifies them.
const flightScript = /<script[^>]*>(self\.__next_f\.push\(.*?)<\/script>/gs
for (const match of text.matchAll(flightScript)) {
inlineFlightBytes += Buffer.byteLength(match[1])
inlineFlightScripts++
}
if (inlineFlightScripts === 0) {
// Every App Router document carries inline Flight scripts; a
// silent zero would corrupt the flight-share metric.
if (text.includes('__next_f')) {
throw new Error(
`[inspect] ${route}: document contains __next_f but the extraction regex matched no inline Flight scripts — the markup shape changed, update the regex in inspectRouteDocument`
)
}
throw new Error(
`[inspect] ${route}: not an App Router document (no __next_f) — this benchmark only measures App Router routes`
)
}
return {
route,
bytes,
gzipBytes,
inlineFlightBytes,
inlineFlightShare: bytes > 0 ? inlineFlightBytes / bytes : 0,
inlineFlightScripts,
}
} finally {
clearTimeout(timeout)
}View on GitHub (pinned to 0ae8c72462)
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).
Example fix
// before const flightScript = /<script[^>]*>(self\.__next_f\.push\(.*?)<\/script>/gs // after — example: the new markup wraps the script with a nonce AND the push // argument is now quoted differently; loosen the tag head and anchor on the push call const flightScript = /<script\b[^>]*>([\s\S]*?self\.__next_f\.push\([\s\S]*?<\/script>/g // (adjust to the actual current shape after inspecting the document)
Defensive patterns
Strategy: validation
Validate before calling
// sanity-check the extraction regex against a current document before relying on it:
function countFlightScripts(html: string): number {
const re = /<script[^>]*>(self\.__next_f\.push\(.*?)<\/script>/gs
let n = 0
while (re.exec(html)) n++
return n
}
// in a test: assert countFlightScripts(realCurrentDocument) > 0 Type guard
function isFlightRegexStaleError(err: unknown): boolean {
return err instanceof Error && /extraction regex matched no inline Flight scripts/.test(err.message)
} Try / catch
// This is a tooling bug, not a runtime blip — don't silently swallow it.
try {
await inspectRouteDocument(url, route, timeoutMs)
} catch (err) {
if (isFlightRegexStaleError(err)) {
console.error('Flight script markup changed. Curl the route, grep __next_f, and update the regex in inspectRouteDocument.')
}
throw err
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Invalid numeric value for --${key}: ${value}
- --routes cannot be empty
- Each route must start with '/': ${route}
- Invalid --scenario value: ${scenarioRaw}. Use e2e|minimal-se
- Invalid --stream-mode value: ${streamModeRaw}. Use node
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/12876cec29af5550.
Report an issue: GitHub.