vercel / vercel/next.js

`forbidden.tsx` not being used when `forbidden()` was thrown in `layout.tsx`

Open
#83,671 3 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
142k
Forks
32.4k
Avg merge
2d 14h
Merged PRs (30d)
351

Description

Link to the code that reproduces this issue

https://codesandbox.io/p/devbox/73l4ht

To Reproduce
  1. Add experimental: { authInterrupts: true } to next.config.js
  2. Create some route
  3. Add forbidden.tsx to this route
  4. Add layout.tsx file to this route and throw forbidden() in it
Current vs. Expected behavior

Current behavior:
Next.js generic error page shows up with code 403.

Image

--

Expected behavior:
forbidden.tsx content should be used instead.

Provide environment information
Operating System:
  Platform: win32
  Arch: x64
  Version: Windows 11 Pro
  Available memory (MB): 31913
  Available CPU cores: 24
Binaries:
  Node: 22.15.0
  npm: 11.5.2
  Yarn: 1.22.22
  pnpm: 10.14.0
Relevant Packages:
  next: 15.4.6 // There is a newer version (15.5.3) available, upgrade recommended! 
  eslint-config-next: 15.4.6
  react: 19.1.1
  react-dom: 19.1.1
  typescript: 5.8.3
Next.js Config:
  output: N/A
Which area(s) are affected? (Select all that apply)

Not sure

Which stage(s) are affected? (Select all that apply)

next dev (local), next start (local)

Additional context
  • Tested with 15.5.3 version of next.js. Behavior didn't change.
  • Expected behavior happens if layout.tsx exists, but forbidden() is thrown on page.tsx

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked CodeSandbox and reproduce the issue using the route's layout.tsx, forbidden.tsx, and the authInterrupts setting in next.config.js. Compare behavior in next dev and next start; the work is done when throwing forbidden() from layout.tsx renders the route's forbidden.tsx content instead of the generic 403 page.

Written by the indexing model from the issue text.

Assessment

Tech stack
next.js, react, typescript
Domain
frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.