router icon indicating copy to clipboard operation
router copied to clipboard

notFound in page loader cause layout loader to not properly finish, returning undefined

Open eisterman opened this issue 8 months ago • 3 comments

Which project does this relate to?

Start

Describe the bug

When with Tanstack/start I have a layout of this type:

posts.$postId.tsx
posts.route.tsx

with a loader in each of the files. Where in posts.$postId.tsx the loader throw notFound() and the loader for the layout posts.route.tsx is not resolved, the layout get rendered in any case, but with Route.useLoaderData() being undefined.

If I go to a posts/postId URL that doesn't exists from a previous state where the Layout was properly rendered, there is no error because the layout loader is not being rerunned. When I go to a page that throw notFound from a previous state where the layout was not rendered, the error appear.

The most simple way to make this error appear starting from start-basic:

  1. Introduce a sufficiently large artificial delay in the Layout Loader (for example posts.$postId.tsx)
  2. Manually go to an URL for a resource that doesn't exists (like /posts/i-do-not-exist)

During my tests I tried to introduce the delay inside the Layout Loader directly and inside the fetchPosts() Server Function, with the same result.

Your Example Website or App

https://github.com/eisterman/tanstack-notfound-bug

Steps to Reproduce the Bug or Issue

  1. Launch the app
  2. Navigate manually to a Post page that doesn't exist like /posts/i-do-not-exist

Expected behavior

As a user I expect that I see the notFoundComponent for the route that raised the notFound, with the posts.route.tsx still working.

Screenshots or Videos

Image

Platform

  • OS: Linux
  • Browser: Same on Brave and Firefox
  • Version: Brave Version 1.76.82 Chromium: 134.0.6998.178 and Firefox 136

Additional context

As delay I have used a traditional await new Promise((resolve) => setTimeout(resolve, 500)); with various values of the timers. In my tests for the start-basic template a value greater than 300 started to make the error appear sometimes, with greater then 500 making it appear always.

eisterman avatar Apr 01 '25 18:04 eisterman

I have reproduced properly the bug into the start-basic template, and updated the content of the issue.

eisterman avatar Apr 03 '25 10:04 eisterman

Bug still present in 1.120.5

eisterman avatar May 22 '25 08:05 eisterman

The error appear ONLY with throw notFound() and not when the posts route return an error.

eisterman avatar May 31 '25 14:05 eisterman

Working as expected now

eisterman avatar Jul 15 '25 15:07 eisterman