next.js/test/e2e/app-dir/instant-validation/instant-validation-parallel-slots.test.ts
instant-validation-parallel-slots.test.ts649 lines29.9 KB
import { nextTestSetup } from 'e2e-utils'
import {
  expectNoBuildValidationErrors,
  extractBuildValidationError,
  waitForValidation,
} from 'e2e-utils/instant-validation'
import { retry, waitForNoErrorToast } from '../../../lib/next-test-utils'
import type { Playwright } from '../../../lib/next-webdriver'

describe('instant validation - parallel slot configs', () => {
  const { next, skipped, isNextDev, isNextStart, isTurbopack } = nextTestSetup({
    files: __dirname,
    skipStart: true,
    skipDeployment: true,
    env: {
      NEXT_TEST_LOG_VALIDATION: '1',
    },
  })
  if (skipped) return

  if (isNextStart && !isTurbopack) {
    // TODO(instant-validation-build): snapshot tests for webpack
    it.skip('TODO: snapshot tests for webpack', () => {})
    return
  }

  if (isNextStart) {
    beforeAll(async () => {
      await next.build({ args: ['--experimental-build-mode', 'compile'] })
    })
    afterEach(async () => {
      await next.stop()
    })
  } else {
    beforeAll(async () => {
      await next.start()
    })
  }

  let currentCliOutputIndex = 0
  beforeEach(() => {
    currentCliOutputIndex = next.cliOutput.length
  })

  function getCliOutputSinceMark(): string {
    if (next.cliOutput.length < currentCliOutputIndex) {
      currentCliOutputIndex = 0
    }
    return next.cliOutput.slice(currentCliOutputIndex)
  }

  const prerender = async (pathname: string) => {
    const args = [
      '--experimental-build-mode',
      'generate',
      '--debug-build-paths',
      `app${pathname}/page.tsx`,
    ]
    return await next.build({ args })
  }

  const NO_VALIDATION_ERRORS_WAIT: Parameters<typeof waitForNoErrorToast>[1] = {
    waitInMs: 500,
  }

  async function expectNoDevValidationErrors(
    browser: Playwright,
    url: string
  ): Promise<void> {
    await waitForValidation(url, getCliOutputSinceMark)
    await waitForNoErrorToast(browser, NO_VALIDATION_ERRORS_WAIT)
  }

  const cases = isNextDev
    ? [
        { isClientNav: false, description: 'dev - initial load' },
        { isClientNav: true, description: 'dev - client navigation' },
      ]
    : [{ isClientNav: false, description: 'build' }]

  describe.each(cases)('$description', ({ isClientNav }) => {
    async function navigateTo(href: string) {
      if (!isClientNav) {
        if (isNextStart) {
          await next.start()
        }
        const browser = await next.browser(href)
        await browser.elementByCss('main')
        return browser
      }

      const browser = await next.browser('/suspense-in-root')
      await browser
        .elementByCss(`[data-link-type="soft"][href="${href}"]`)
        .click()
      await retry(
        async () => {
          expect(await browser.url()).toContain(href)
        },
        undefined,
        100,
        'wait for url to change'
      )
      return browser
    }

    describe('config on slot page', () => {
      it('catches unsuspended dynamic content in children when config is on slot page', async () => {
        if (isNextDev) {
          const browser = await navigateTo(
            '/suspense-in-root/parallel/slot-config-only'
          )
          await expect(browser).toDisplayCollapsedRedbox(`
           {
             "cause": [
               {
                 "label": "Caused by: Instant Validation",
                 "source": "app/suspense-in-root/parallel/slot-config-only/@slot/page.tsx (1:33) @ unstable_instant
           > 1 | export const unstable_instant = true
               |                                 ^",
                 "stack": [
                   "unstable_instant app/suspense-in-root/parallel/slot-config-only/@slot/page.tsx (1:33)",
                   "Set.forEach <anonymous>",
                 ],
               },
             ],
             "code": "E1166",
             "description": "Next.js encountered runtime data during the initial render.",
             "environmentLabel": "Server",
             "label": "Instant",
             "source": "app/suspense-in-root/parallel/slot-config-only/page.tsx (4:16) @ ChildrenPage
           > 4 |   await cookies()
               |                ^",
             "stack": [
               "ChildrenPage app/suspense-in-root/parallel/slot-config-only/page.tsx (4:16)",
             ],
           }
          `)
        } else {
          const result = await prerender(
            '/suspense-in-root/parallel/slot-config-only'
          )
          expect(extractBuildValidationError(result.cliOutput))
            .toMatchInlineSnapshot(`
           "Error: Route "/suspense-in-root/parallel/slot-config-only": Next.js encountered runtime data during the initial render.

           \`cookies()\`, \`headers()\`, \`params\`, or \`searchParams\` accessed outside of \`<Suspense>\` blocks navigation, leading to a slower user experience.

           Ways to fix this:
             - Move the data access into a child component within a <Suspense> boundary
             - Use \`generateStaticParams\` to make route params static
             - Set \`export const instant = false\` to allow a blocking route

           Learn more: https://nextjs.org/docs/messages/blocking-route
               at body (<anonymous>)
               at html (<anonymous>)
               at a (<anonymous>)
           Build-time instant validation failed for route "/suspense-in-root/parallel/slot-config-only".
           To get a more detailed stack trace and pinpoint the issue, try one of the following:
             - Start the app in development mode by running \`next dev\`, then open "/suspense-in-root/parallel/slot-config-only" in your browser to investigate the error.
             - Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
           Stopping prerender due to instant validation errors."
          `)
          expect(result.exitCode).toBe(1)
        }
      })

      it('catches unsuspended dynamic content in children when config is on slot layout', async () => {
        if (isNextDev) {
          const browser = await navigateTo(
            '/suspense-in-root/parallel/slot-layout-config'
          )
          await expect(browser).toDisplayCollapsedRedbox(`
           {
             "cause": [
               {
                 "label": "Caused by: Instant Validation",
                 "source": "app/suspense-in-root/parallel/slot-layout-config/@slot/layout.tsx (3:33) @ unstable_instant
           > 3 | export const unstable_instant = true
               |                                 ^",
                 "stack": [
                   "unstable_instant app/suspense-in-root/parallel/slot-layout-config/@slot/layout.tsx (3:33)",
                   "Set.forEach <anonymous>",
                 ],
               },
             ],
             "code": "E1166",
             "description": "Next.js encountered runtime data during the initial render.",
             "environmentLabel": "Server",
             "label": "Instant",
             "source": "app/suspense-in-root/parallel/slot-layout-config/page.tsx (4:16) @ ChildrenPage
           > 4 |   await cookies()
               |                ^",
             "stack": [
               "ChildrenPage app/suspense-in-root/parallel/slot-layout-config/page.tsx (4:16)",
             ],
           }
          `)
        } else {
          const result = await prerender(
            '/suspense-in-root/parallel/slot-layout-config'
          )
          expect(extractBuildValidationError(result.cliOutput))
            .toMatchInlineSnapshot(`
           "Error: Route "/suspense-in-root/parallel/slot-layout-config": Next.js encountered runtime data during the initial render.

           \`cookies()\`, \`headers()\`, \`params\`, or \`searchParams\` accessed outside of \`<Suspense>\` blocks navigation, leading to a slower user experience.

           Ways to fix this:
             - Move the data access into a child component within a <Suspense> boundary
             - Use \`generateStaticParams\` to make route params static
             - Set \`export const instant = false\` to allow a blocking route

           Learn more: https://nextjs.org/docs/messages/blocking-route
               at body (<anonymous>)
               at html (<anonymous>)
               at a (<anonymous>)
           Build-time instant validation failed for route "/suspense-in-root/parallel/slot-layout-config".
           To get a more detailed stack trace and pinpoint the issue, try one of the following:
             - Start the app in development mode by running \`next dev\`, then open "/suspense-in-root/parallel/slot-layout-config" in your browser to investigate the error.
             - Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
           Stopping prerender due to instant validation errors."
          `)
          expect(result.exitCode).toBe(1)
        }
      })

      it('catches unsuspended dynamic content in children when runtime config is on slot page', async () => {
        if (isNextDev) {
          const browser = await navigateTo(
            '/suspense-in-root/parallel/slot-runtime-config'
          )
          await expect(browser).toDisplayCollapsedRedbox(`
           {
             "cause": [
               {
                 "label": "Caused by: Instant Validation",
                 "source": "app/suspense-in-root/parallel/slot-runtime-config/@slot/page.tsx (4:33) @ unstable_instant
           > 4 | export const unstable_instant = true
               |                                 ^",
                 "stack": [
                   "unstable_instant app/suspense-in-root/parallel/slot-runtime-config/@slot/page.tsx (4:33)",
                   "Set.forEach <anonymous>",
                 ],
               },
             ],
             "code": "E1166",
             "description": "Next.js encountered runtime data during the initial render.",
             "environmentLabel": "Server",
             "label": "Instant",
             "source": "app/suspense-in-root/parallel/slot-runtime-config/page.tsx (4:16) @ ChildrenPage
           > 4 |   await cookies()
               |                ^",
             "stack": [
               "ChildrenPage app/suspense-in-root/parallel/slot-runtime-config/page.tsx (4:16)",
             ],
           }
          `)
        } else {
          const result = await prerender(
            '/suspense-in-root/parallel/slot-runtime-config'
          )
          expect(extractBuildValidationError(result.cliOutput))
            .toMatchInlineSnapshot(`
           "Error: Route "/suspense-in-root/parallel/slot-runtime-config": Next.js encountered runtime data during the initial render.

           \`cookies()\`, \`headers()\`, \`params\`, or \`searchParams\` accessed outside of \`<Suspense>\` blocks navigation, leading to a slower user experience.

           Ways to fix this:
             - Move the data access into a child component within a <Suspense> boundary
             - Use \`generateStaticParams\` to make route params static
             - Set \`export const instant = false\` to allow a blocking route

           Learn more: https://nextjs.org/docs/messages/blocking-route
               at body (<anonymous>)
               at html (<anonymous>)
               at a (<anonymous>)
           Build-time instant validation failed for route "/suspense-in-root/parallel/slot-runtime-config".
           To get a more detailed stack trace and pinpoint the issue, try one of the following:
             - Start the app in development mode by running \`next dev\`, then open "/suspense-in-root/parallel/slot-runtime-config" in your browser to investigate the error.
             - Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
           Stopping prerender due to instant validation errors."
          `)
          expect(result.exitCode).toBe(1)
        }
      })
    })

    describe('config on children with slot', () => {
      it('catches unsuspended dynamic content in slot when config is on children page', async () => {
        if (isNextDev) {
          const browser = await navigateTo(
            '/suspense-in-root/parallel/children-config-with-slot'
          )
          await expect(browser).toDisplayCollapsedRedbox(`
           {
             "cause": [
               {
                 "label": "Caused by: Instant Validation",
                 "source": "app/suspense-in-root/parallel/children-config-with-slot/page.tsx (1:33) @ unstable_instant
           > 1 | export const unstable_instant = true
               |                                 ^",
                 "stack": [
                   "unstable_instant app/suspense-in-root/parallel/children-config-with-slot/page.tsx (1:33)",
                   "Set.forEach <anonymous>",
                 ],
               },
             ],
             "code": "E1166",
             "description": "Next.js encountered runtime data during the initial render.",
             "environmentLabel": "Server",
             "label": "Instant",
             "source": "app/suspense-in-root/parallel/children-config-with-slot/@slot/page.tsx (4:16) @ SlotPage
           > 4 |   await cookies()
               |                ^",
             "stack": [
               "SlotPage app/suspense-in-root/parallel/children-config-with-slot/@slot/page.tsx (4:16)",
             ],
           }
          `)
        } else {
          const result = await prerender(
            '/suspense-in-root/parallel/children-config-with-slot'
          )
          expect(extractBuildValidationError(result.cliOutput))
            .toMatchInlineSnapshot(`
           "Error: Route "/suspense-in-root/parallel/children-config-with-slot": Next.js encountered runtime data during the initial render.

           \`cookies()\`, \`headers()\`, \`params\`, or \`searchParams\` accessed outside of \`<Suspense>\` blocks navigation, leading to a slower user experience.

           Ways to fix this:
             - Move the data access into a child component within a <Suspense> boundary
             - Use \`generateStaticParams\` to make route params static
             - Set \`export const instant = false\` to allow a blocking route

           Learn more: https://nextjs.org/docs/messages/blocking-route
               at div (<anonymous>)
               at body (<anonymous>)
               at html (<anonymous>)
               at a (<anonymous>)
           Build-time instant validation failed for route "/suspense-in-root/parallel/children-config-with-slot".
           To get a more detailed stack trace and pinpoint the issue, try one of the following:
             - Start the app in development mode by running \`next dev\`, then open "/suspense-in-root/parallel/children-config-with-slot" in your browser to investigate the error.
             - Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
           Stopping prerender due to instant validation errors."
          `)
          expect(result.exitCode).toBe(1)
        }
      })

      it('catches unsuspended dynamic content in both slots when config is on fork-point layout', async () => {
        if (isNextDev) {
          const browser = await navigateTo(
            '/suspense-in-root/parallel/fork-layout-config-with-slot'
          )
          await expect(browser).toDisplayCollapsedRedbox(`
           [
             {
               "cause": [
                 {
                   "label": "Caused by: Instant Validation",
                   "source": "app/suspense-in-root/parallel/fork-layout-config-with-slot/layout.tsx (3:33) @ unstable_instant
           > 3 | export const unstable_instant = true
               |                                 ^",
                   "stack": [
                     "unstable_instant app/suspense-in-root/parallel/fork-layout-config-with-slot/layout.tsx (3:33)",
                     "Set.forEach <anonymous>",
                   ],
                 },
               ],
               "code": "E1166",
               "description": "Next.js encountered runtime data during the initial render.",
               "environmentLabel": "Server",
               "label": "Instant",
               "source": "app/suspense-in-root/parallel/fork-layout-config-with-slot/@slot/page.tsx (4:16) @ SlotPage
           > 4 |   await cookies()
               |                ^",
               "stack": [
                 "SlotPage app/suspense-in-root/parallel/fork-layout-config-with-slot/@slot/page.tsx (4:16)",
               ],
             },
             {
               "cause": [
                 {
                   "label": "Caused by: Instant Validation",
                   "source": "app/suspense-in-root/parallel/fork-layout-config-with-slot/layout.tsx (3:33) @ unstable_instant
           > 3 | export const unstable_instant = true
               |                                 ^",
                   "stack": [
                     "unstable_instant app/suspense-in-root/parallel/fork-layout-config-with-slot/layout.tsx (3:33)",
                     "Set.forEach <anonymous>",
                   ],
                 },
               ],
               "code": "E1166",
               "description": "Next.js encountered runtime data during the initial render.",
               "environmentLabel": "Server",
               "label": "Instant",
               "source": "app/suspense-in-root/parallel/fork-layout-config-with-slot/page.tsx (4:16) @ ChildrenPage
           > 4 |   await cookies()
               |                ^",
               "stack": [
                 "ChildrenPage app/suspense-in-root/parallel/fork-layout-config-with-slot/page.tsx (4:16)",
               ],
             },
           ]
          `)
        } else {
          const result = await prerender(
            '/suspense-in-root/parallel/fork-layout-config-with-slot'
          )
          expect(extractBuildValidationError(result.cliOutput))
            .toMatchInlineSnapshot(`
           "Error: Route "/suspense-in-root/parallel/fork-layout-config-with-slot": Next.js encountered runtime data during the initial render.

           \`cookies()\`, \`headers()\`, \`params\`, or \`searchParams\` accessed outside of \`<Suspense>\` blocks navigation, leading to a slower user experience.

           Ways to fix this:
             - Move the data access into a child component within a <Suspense> boundary
             - Use \`generateStaticParams\` to make route params static
             - Set \`export const instant = false\` to allow a blocking route

           Learn more: https://nextjs.org/docs/messages/blocking-route
               at div (<anonymous>)
               at body (<anonymous>)
               at html (<anonymous>)
               at a (<anonymous>)
           Error: Route "/suspense-in-root/parallel/fork-layout-config-with-slot": Next.js encountered runtime data during the initial render.

           \`cookies()\`, \`headers()\`, \`params\`, or \`searchParams\` accessed outside of \`<Suspense>\` blocks navigation, leading to a slower user experience.

           Ways to fix this:
             - Move the data access into a child component within a <Suspense> boundary
             - Use \`generateStaticParams\` to make route params static
             - Set \`export const instant = false\` to allow a blocking route

           Learn more: https://nextjs.org/docs/messages/blocking-route
               at body (<anonymous>)
               at html (<anonymous>)
               at b (<anonymous>)
           Build-time instant validation failed for route "/suspense-in-root/parallel/fork-layout-config-with-slot".
           To get a more detailed stack trace and pinpoint the issue, try one of the following:
             - Start the app in development mode by running \`next dev\`, then open "/suspense-in-root/parallel/fork-layout-config-with-slot" in your browser to investigate the error.
             - Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
           Stopping prerender due to instant validation errors."
          `)
          expect(result.exitCode).toBe(1)
        }
      })
    })

    describe('valid parallel slot configs', () => {
      it('valid - config on both children and slot pages', async () => {
        if (isNextDev) {
          const browser = await navigateTo(
            '/suspense-in-root/parallel/both-configs'
          )
          await expectNoDevValidationErrors(browser, await browser.url())
        } else {
          const result = await prerender(
            '/suspense-in-root/parallel/both-configs'
          )
          expectNoBuildValidationErrors(result)
        }
      })

      it('valid - config on slot, children dynamic content inside Suspense', async () => {
        if (isNextDev) {
          const browser = await navigateTo(
            '/suspense-in-root/parallel/slot-config-children-suspended'
          )
          await expectNoDevValidationErrors(browser, await browser.url())
        } else {
          const result = await prerender(
            '/suspense-in-root/parallel/slot-config-children-suspended'
          )
          expectNoBuildValidationErrors(result)
        }
      })
    })

    describe('conditional slot rendering', () => {
      it('valid - both slots render, no cookies', async () => {
        const href =
          '/suspense-in-root/parallel/conditional-breadcrumbs/show-both/unblocked'
        if (isNextDev) {
          const browser = await navigateTo(href)
          await expectNoDevValidationErrors(browser, await browser.url())
        } else {
          const result = await prerender(href)
          expectNoBuildValidationErrors(result)
        }
      })

      it('valid - only configured children slot renders, no cookies', async () => {
        const href =
          '/suspense-in-root/parallel/conditional-breadcrumbs/show-only-children/unblocked'
        if (isNextDev) {
          const browser = await navigateTo(href)
          await expectNoDevValidationErrors(browser, await browser.url())
        } else {
          const result = await prerender(href)
          expectNoBuildValidationErrors(result)
        }
      })

      it('valid - only configured children slot renders, breadcrumbs blocked', async () => {
        const href =
          '/suspense-in-root/parallel/conditional-breadcrumbs/show-only-children/blocked'
        if (isNextDev) {
          const browser = await navigateTo(href)
          await expectNoDevValidationErrors(browser, await browser.url())
        } else {
          const result = await prerender(href)
          expectNoBuildValidationErrors(result)
        }
      })

      it('errors when both slots render and breadcrumbs calls cookies', async () => {
        const href =
          '/suspense-in-root/parallel/conditional-breadcrumbs/show-both/blocked'
        if (isNextDev) {
          const browser = await navigateTo(href)
          await expect(browser).toDisplayCollapsedRedbox(`
           {
             "cause": [
               {
                 "label": "Caused by: Instant Validation",
                 "source": "app/suspense-in-root/parallel/conditional-breadcrumbs/show-both/blocked/page.tsx (1:33) @ unstable_instant
           > 1 | export const unstable_instant = true
               |                                 ^",
                 "stack": [
                   "unstable_instant app/suspense-in-root/parallel/conditional-breadcrumbs/show-both/blocked/page.tsx (1:33)",
                   "Set.forEach <anonymous>",
                 ],
               },
             ],
             "code": "E1166",
             "description": "Next.js encountered runtime data during the initial render.",
             "environmentLabel": "Server",
             "label": "Instant",
             "source": "app/suspense-in-root/parallel/conditional-breadcrumbs/show-both/@breadcrumbs/blocked/page.tsx (3:16) @ BreadcrumbsPage
           > 3 |   await cookies()
               |                ^",
             "stack": [
               "BreadcrumbsPage app/suspense-in-root/parallel/conditional-breadcrumbs/show-both/@breadcrumbs/blocked/page.tsx (3:16)",
             ],
           }
          `)
        } else {
          const result = await prerender(href)
          expect(extractBuildValidationError(result.cliOutput))
            .toMatchInlineSnapshot(`
           "Error: Route "/suspense-in-root/parallel/conditional-breadcrumbs/show-both/blocked": Next.js encountered runtime data during the initial render.

           \`cookies()\`, \`headers()\`, \`params\`, or \`searchParams\` accessed outside of \`<Suspense>\` blocks navigation, leading to a slower user experience.

           Ways to fix this:
             - Move the data access into a child component within a <Suspense> boundary
             - Use \`generateStaticParams\` to make route params static
             - Set \`export const instant = false\` to allow a blocking route

           Learn more: https://nextjs.org/docs/messages/blocking-route
               at div (<anonymous>)
               at main (<anonymous>)
               at body (<anonymous>)
               at html (<anonymous>)
               at a (<anonymous>)
           Build-time instant validation failed for route "/suspense-in-root/parallel/conditional-breadcrumbs/show-both/blocked".
           To get a more detailed stack trace and pinpoint the issue, try one of the following:
             - Start the app in development mode by running \`next dev\`, then open "/suspense-in-root/parallel/conditional-breadcrumbs/show-both/blocked" in your browser to investigate the error.
             - Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
           Stopping prerender due to instant validation errors."
          `)
          expect(result.exitCode).toBe(1)
        }
      })

      it('errors when configured children slot is hidden, no cookies', async () => {
        const href =
          '/suspense-in-root/parallel/conditional-breadcrumbs/show-only-breadcrumbs/unblocked'
        if (isNextDev) {
          const browser = await navigateTo(href)
          await expect(browser).toDisplayCollapsedRedbox(`
           {
             "description": "Route "/suspense-in-root/parallel/conditional-breadcrumbs/show-only-breadcrumbs/unblocked": Could not validate \`unstable_instant\` because the target segment was prevented from rendering for an unknown reason.",
             "environmentLabel": "Server",
             "label": "Console Error",
             "source": "app/suspense-in-root/parallel/conditional-breadcrumbs/show-only-breadcrumbs/unblocked/page.tsx (1:33) @ unstable_instant
           > 1 | export const unstable_instant = true
               |                                 ^",
             "stack": [
               "unstable_instant app/suspense-in-root/parallel/conditional-breadcrumbs/show-only-breadcrumbs/unblocked/page.tsx (1:33)",
             ],
           }
          `)
        } else {
          const result = await prerender(href)
          expect(extractBuildValidationError(result.cliOutput))
            .toMatchInlineSnapshot(`
           "Error: Route "/suspense-in-root/parallel/conditional-breadcrumbs/show-only-breadcrumbs/unblocked": Could not validate \`unstable_instant\` because the target segment was prevented from rendering for an unknown reason.
               at ignore-listed frames
           Build-time instant validation failed for route "/suspense-in-root/parallel/conditional-breadcrumbs/show-only-breadcrumbs/unblocked".
           To get a more detailed stack trace and pinpoint the issue, try one of the following:
             - Start the app in development mode by running \`next dev\`, then open "/suspense-in-root/parallel/conditional-breadcrumbs/show-only-breadcrumbs/unblocked" in your browser to investigate the error.
             - Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
           Stopping prerender due to instant validation errors."
          `)
          expect(result.exitCode).toBe(1)
        }
      })

      it('errors when configured children slot is hidden, breadcrumbs blocked', async () => {
        const href =
          '/suspense-in-root/parallel/conditional-breadcrumbs/show-only-breadcrumbs/blocked'
        if (isNextDev) {
          const browser = await navigateTo(href)
          await expect(browser).toDisplayCollapsedRedbox(`
           {
             "description": "Route "/suspense-in-root/parallel/conditional-breadcrumbs/show-only-breadcrumbs/blocked": Could not validate \`unstable_instant\` because the target segment was prevented from rendering for an unknown reason.",
             "environmentLabel": "Server",
             "label": "Console Error",
             "source": "app/suspense-in-root/parallel/conditional-breadcrumbs/show-only-breadcrumbs/blocked/page.tsx (1:33) @ unstable_instant
           > 1 | export const unstable_instant = true
               |                                 ^",
             "stack": [
               "unstable_instant app/suspense-in-root/parallel/conditional-breadcrumbs/show-only-breadcrumbs/blocked/page.tsx (1:33)",
             ],
           }
          `)
        } else {
          const result = await prerender(href)
          expect(extractBuildValidationError(result.cliOutput))
            .toMatchInlineSnapshot(`
           "Error: Route "/suspense-in-root/parallel/conditional-breadcrumbs/show-only-breadcrumbs/blocked": Could not validate \`unstable_instant\` because the target segment was prevented from rendering for an unknown reason.
               at ignore-listed frames
           Build-time instant validation failed for route "/suspense-in-root/parallel/conditional-breadcrumbs/show-only-breadcrumbs/blocked".
           To get a more detailed stack trace and pinpoint the issue, try one of the following:
             - Start the app in development mode by running \`next dev\`, then open "/suspense-in-root/parallel/conditional-breadcrumbs/show-only-breadcrumbs/blocked" in your browser to investigate the error.
             - Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
           Stopping prerender due to instant validation errors."
          `)
          expect(result.exitCode).toBe(1)
        }
      })
    })
  })
})
Quest for Codev2.0.0
/
SIGN IN