Which project does this relate to?
Start
Describe the bug
We prerender a full site (774 pages) from a CMS at build time, so a build that fails must fail loudly — a CMS hiccup during the build must never ship a site with missing pages. While hardening that, we found that the prerenderer cannot deliver this promise: a page whose loader throws is logged, announced for a retry that never happens, and the build exits 0 with the page missing from the output. We carry a process.on("unhandledRejection") guard in vite.config.ts to compensate. Two bugs in start-plugin-core/src/prerender.ts:
retryCount never retries. The retry calls addCrawlPageTask(page), which returns early because the path is already in seen. No retry happens, and the error is swallowed (the failOnError branch was not taken). Fix: seen.delete(page.path) before re-adding.
failOnError cannot fail the build. queue.add(...) is never awaited; its rejection becomes an unhandled rejection while Queue.start() resolves via onSettled, which fires on failure too. Vite exits 0. Fix: collect the rejections and rethrow after queue.start().
Complete minimal reproducer
https://github.com/fullheart/tanstack-start-issue-8120
Steps to Reproduce the Bug or Issue
npm install && npm run build; echo $? — the log shows one loader attempt, prints Encountered error, retrying: /broken in 500ms, never retries, and exits 0; .output/public/broken/index.html does not exist. npm run check asserts all three.
Expected behavior
retryCount: 2 attempts the page three times; if it still fails, failOnError: true makes the build exit non-zero.
Additional context
Workaround until fixed — in vite.config.ts, make the swallowed rejection loud, and put retries into your own data layer instead of retryCount:
process.on("unhandledRejection", (error) => {
console.error(error);
process.exit(1);
});
Platform
- Router / Start Version: @tanstack/react-start 1.168.46
- OS: Linux
- Bundler: vite
- Bundler Version: 8.1.5
Which project does this relate to?
Start
Describe the bug
We prerender a full site (774 pages) from a CMS at build time, so a build that fails must fail loudly — a CMS hiccup during the build must never ship a site with missing pages. While hardening that, we found that the prerenderer cannot deliver this promise: a page whose loader throws is logged, announced for a retry that never happens, and the build exits 0 with the page missing from the output. We carry a
process.on("unhandledRejection")guard invite.config.tsto compensate. Two bugs instart-plugin-core/src/prerender.ts:retryCountnever retries. The retry callsaddCrawlPageTask(page), which returns early because the path is already inseen. No retry happens, and the error is swallowed (thefailOnErrorbranch was not taken). Fix:seen.delete(page.path)before re-adding.failOnErrorcannot fail the build.queue.add(...)is never awaited; its rejection becomes an unhandled rejection whileQueue.start()resolves viaonSettled, which fires on failure too. Vite exits 0. Fix: collect the rejections and rethrow afterqueue.start().Complete minimal reproducer
https://github.com/fullheart/tanstack-start-issue-8120
Steps to Reproduce the Bug or Issue
npm install && npm run build; echo $?— the log shows one loader attempt, printsEncountered error, retrying: /broken in 500ms, never retries, and exits0;.output/public/broken/index.htmldoes not exist.npm run checkasserts all three.Expected behavior
retryCount: 2attempts the page three times; if it still fails,failOnError: truemakes the build exit non-zero.Additional context
Workaround until fixed — in
vite.config.ts, make the swallowed rejection loud, and put retries into your own data layer instead ofretryCount:Platform