Repository: next.js
Issue: Calling notFound() in ISR generates static files in app router.
Labels: bug

### Link to the code that reproduces this issue

https://github.com/peterlidee/isr-not-found-bug

### To Reproduce

1. Run next build
2. Check build folder: `.next/app/post/a.html` and `.next/pages/post2/a.html` exist (SSG)
3. Run next start
4. Visit `/post/a` (app router) and `/post2/a` (pages router). Pages appear as expected.
5. Visit `/post/b` (app router) and `/post2/b` (pages router). Pages appear as expected.  (ISR works confirmed)
6. Visit `/post/c` (app router) and `/post2/c` (pages router). 404 as expected. (`{ notfound: true }` and `notFound()` work)
7. Check build pages folder: `.next/pages/post2/` now contains 2 static html files: `a.html` and `b.html`. No `c.html` because we returned `{ notfound: true }` from `getStaticProps`. This is as expected.
8. Check build app folder: `.next/app/post/` now contains 3 static html files: `a.html` and `b.html` as expected but also `c.html`.
9. `c.html` should not have been generated because we called `notFound()`.

### Current vs. Expected behavior

Following the steps from the previous section, I expected `c.html` to *not* exist in the app router build folder but it did exist.

I setup an example running ISR in the app router ([https://github.com/peterlidee/isr-not-found-bug/blob/main/src/app/post/[slug]/page.tsx](https://github.com/peterlidee/isr-not-found-bug/blob/main/src/app/post/%5Bslug%5D/page.tsx)). I use `generateStaticParams` to generate one page: `post/a`:

```
export function generateStaticParams() {
  return [{ slug: 'a' }];
}
```
In the actual functional component, I only allow slugs "a" or "b":

```
export default async function page({ params }: Props) {
  const slug = (await params).slug;
  const validParams = ['a', 'b'];
  if (!validParams.includes(slug)) {
    notFound();
  }
  return <div>post slug: {slug}</div>;
}
```
Slug "a" has been prerendered at build time. When visiting `/post/b`, next will do ISR and generate static html in the app build folder: `.next/app/post/b.html`. This confirms that ISR works.

The problem lies with slug "c" (or anything other then "a" or "b"). When the slug is "c" `notFound()` gets called and we get an error 404 as expected. However, when visiting the build folder we see that a static `c.html` was generated: `.next/app/post/c.html`.

This is unexpected behaviour: we just told next this page doesn't exist so why generate a static file for this? I copied the functionality of this page in the pages router ([https://github.com/peterlidee/isr-not-found-bug/blob/main/src/pages/post2/[slug].tsx](https://github.com/peterlidee/isr-not-found-bug/blob/main/src/pages/post2/%5Bslug%5D.tsx)) (`/post2`) using `getStaticPaths` and `getStaticProps` and in the pages router `c.html` does not get generated in the build folder.

I'm not 100% this is a bug because the app router behaviour is similar in Next 13, 14, 15 and canary.

### Provide environment information

```bash
Operating System:
  Platform: win32
  Arch: x64
  Version: Windows 11 Education
  Available memory (MB): 32617
  Available CPU cores: 16
Binaries:
  Node: 20.17.0
  npm: 10.8.2
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 15.0.3 // Latest available version is detected (15.0.3).
  eslint-config-next: 15.0.3
  react: 19.0.0-rc-66855b96-20241106
  react-dom: 19.0.0-rc-66855b96-20241106
  typescript: 5.6.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 build (local), next start (local)

### Additional context

_No response_