vercel/next.js · error

[inspect] ${route}: not an App Router document (no __next_f)

Error message

[inspect] ${route}: not an App Router document (no __next_f) — this benchmark only measures App Router routes

What it means

Thrown by inspectRouteDocument in the render-pipeline server benchmark when the fetched HTML for a route contains no inline Flight script (no self.__next_f.push(...) blocks). The benchmark only measures App Router routes, whose server-rendered documents always embed Flight data as inline scripts; a document without them is a Pages Router route, a static 404, a redirect, or otherwise not representative. Refusing the route prevents the flight-share metric from being silently zeroed out and corrupting the A/B comparison.

Source

Thrown at bench/render-pipeline/benchmark.ts:440

    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)
  }
}

// Closed-loop load generator: each worker issues the next request only after
// the current one completes. This means throughput numbers are accurate for

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Confirm every route in --routes resolves to an app/ App Router page by checking the document HTML contains self.__next_f via curl before running the benchmark.
  2. If the route is genuinely a Pages Router route, exclude it from this benchmark — it cannot be measured here.
  3. Check the server logs / the fetched HTML body for a 404, redirect, or error overlay and fix the underlying route handler.
  4. Verify the fixture app was built (next build) and that the route segment renders the App Router shell, not a static or error page.

Example fix

// before: route is a pages-router page
--routes=/,/about
// about.js lives in pages/, not app/

// after: only app-router routes
--routes=/,/dashboard,/docs
Defensive patterns

Strategy: validation

Validate before calling

// Before benchmarking a route, verify it is an App Router document
async function isAppRouterRoute(url: string): Promise<boolean> {
  const res = await fetch(url, { cache: 'no-store' })
  if (!res.ok) return false
  const html = await res.text()
  return html.includes('self.__next_f')
}

for (const route of routes) {
  if (!(await isAppRouterRoute(base + route))) {
    throw new Error(`${route} is not an App Router route; remove it from --routes`)
  }
}

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: Pointing --routes at a Pages Router page (e.g. pages/about.js), a route that returns a 404 or redirect, a static asset URL, or an app route that throws during SSR so the error page (no __next_f) is served. Also triggered if a custom error boundary or not-found page is rendered instead of the App Router shell.

Common situations: Misconfigured --routes list mixing app/ and pages/ paths; the fixture app was built without the app directory; a dynamic route segment returned notFound(); the dev server answered with a compile-error overlay page instead of the real document.

Related errors


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