You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug?]: syntax errors in ./app.tsx causes uncaught 500 error #1648
When editing app.tsx the website will 500 when the app i in an incorrect state. The dev-overlay is visible for a fraction of a second and then the default browser display is shown. The app is then not being able to get recovered with hmr.
Screen.Recording.2024-10-06.at.04.45.41.mov
When editing a file that app.tsx imports (and renders), the error does not occur:
Screen.Recording.2024-10-06.at.04.47.21.mov
It was slightly different behavior in the context of where I found out about the bug. I am making a sveltelab thingy for the hackathon, a repl powered by stackblitz' webcontainers. There some imports did cause similar 500s.
solidlab2.mp4
routes that are currently rendered can also be edited without 500, it's only app.tsx
basic.mp4
Expected behavior 🤔
To be able to write invalid code without the app getting in to an unrecoverable 500-error.
Steps to reproduce 🕹
Steps:
clone the bare solid start example
pnpm install && pnpm dev
edit src/app.tsx so it is invalid javascript and save
Hmm.. trying to think about who to get to look at this one. HMR behavior here could be related to Vinxi (@nksaraf) or it could be related to solid refresh or the overlay (@lxsmnsyc). Maybe either of them would have a better idea of how this should be working.
Revisited on v2. The setup in the original report is fixed; the bug is still reproducible with Nitro, and the real fix belongs upstream.
Fixed for the no-Nitro case. This was filed against v1, on Vinxi. The dev server now serves an error page that mounts Vite's ErrorOverlay (added in #1942, the PR that removed Vinxi), and Vite's client reloads it on the next update (if (isFirstUpdate && hasErrorOverlay()) location.reload()). Verified on unmodified main with a plugins: [solidStart()] app: break app.tsx, fix it, the page comes back on its own in ~0.5s.
Still broken with nitro(). Nitro implements dispatchFetch, so devServer() steps aside and Nitro renders SSR errors itself using Youch. That page has no /@vite/client and no vite-error-overlay, so it has no HMR connection and qualifies for neither of Vite's recovery paths. Fix the file and nothing reaches the browser. Same app, only difference is nitro() in the plugin list.
Fix belongs in Nitro. I tried patching the src/runtime/internal/error/dev.ts locally to append a Vite client + reload script to the HTML error page, removed all SolidStart-side changes, and the Nitro setup recovered in ~0.5s. So an upstream fix is sufficient on its own.
Cross-linking a sibling case that turned up while looking at this: #2260.
The report here is the eager path. app.tsx is imported eagerly, so a syntax error fails at handler level and you get an error page (Nitro's youch page, per the patch above). Route modules take a different path: they all go through lazy(), and there a syntax error produces no page at all. Solid's server-side lazy has no rejection handler, so the Suspense boundary never settles and renderToStream never calls end(). The shell is flushed and the connection then stays open indefinitely, so the browser shows a blank page and no overlay, because as far as it's concerned the page loaded fine.
Root cause is upstream in Solid: solidjs/solid#2945. Tracked on the Start side in #2260, where there's a local workaround in withAssets that can be dropped once the Solid fix lands.
The status is unchanged for the eager app.tsx path when nitro() is installed:
The app initially renders normally.
Introducing a JSX syntax error in src/app.tsx navigates the browser to Nitro's HTTP 500 / Youch page.
Correcting the file does not recover or reload the page (verified after waiting for the update).
A manual reload immediately renders the corrected app.
The published Nitro package still returns only await youch.toHTML(...) for an HTML development error response. I also checked current Nitro main at 4bfb35a; the same handler still has no /@vite/client or equivalent recovery hook. I could not find a matching Nitro issue or PR implementing recovery.
The separate lazy-route failure tracked in #2260 / solidjs/solid#2945 is now fixed by solid-js@1.9.15 and #2260 has been closed. That fix does not affect this eager handler-level error path.
Conclusion: keep this issue open. Updating Solid is not sufficient; the remaining blocker is still Nitro's development error page needing a Vite/HMR recovery mechanism (or equivalent polling/reload behavior).
Checked this on the 1.x line, since the original report is against v1 on Vinxi. The comments above cover v2.
It still reproduces on 1.x. I used the bare fixture from the 1.x branch (vinxi 0.5.8) and followed the steps from the report in a browser:
Make src/app.tsx invalid. The browser ends up on a 503 Server Unavailable page with no error overlay.
Make the file valid again. The page stays on the 503 and does not recover.
Reload by hand. The fixed app renders.
Cause. The 503 page is Vinxi's dev error handler (vinxi/lib/dev-error.js). A syntax error in app.tsx makes ssrLoadModule fail on the SSR handler's module graph (entry-server → StartServer → app.tsx), so none of SolidStart's runtime code runs. Vinxi then sends a static HTML page without /@vite/client. The page has no HMR connection, so nothing tells it when the file is fixed.
Why SolidStart 1.x cannot fix this cleanly.
Vinxi ignores Nitro's devErrorHandler option (the line that would read it is commented out in vinxi/lib/nitro-dev.js), so SolidStart cannot replace the error page through config.
The failure happens while loading SolidStart's own handler module, before any SolidStart code can catch it.
The only SolidStart-side workaround would be to point the SSR router at a dev-only wrapper that imports entry-server dynamically and renders its own recovery page. That changes how 1.x loads its handler, which is too large a change for the maintenance line to work around a Vinxi bug.
The fix belongs in Vinxi's dev error page: it needs a Vite client, or a reload-when-the-server-recovers script like the one in the Nitro patch above. In v2 SolidStart owns the dev server, which is why the no-Nitro case could be fixed there.
Workaround on 1.x: after fixing the file, reload the page by hand.
Activity
ryansolid commentedon Oct 31, 2024
Hmm.. trying to think about who to get to look at this one. HMR behavior here could be related to Vinxi (@nksaraf) or it could be related to solid refresh or the overlay (@lxsmnsyc). Maybe either of them would have a better idea of how this should be working.
atilafassina commentedon Feb 12, 2025
@lxsmnsyc can you please let us know if this is a Solid-Refresh issue? 👀
birkskyum commentedon Jul 27, 2026
Revisited on v2. The setup in the original report is fixed; the bug is still reproducible with Nitro, and the real fix belongs upstream.
Fixed for the no-Nitro case. This was filed against v1, on Vinxi. The dev server now serves an error page that mounts Vite's
ErrorOverlay(added in #1942, the PR that removed Vinxi), and Vite's client reloads it on the next update (if (isFirstUpdate && hasErrorOverlay()) location.reload()). Verified on unmodifiedmainwith aplugins: [solidStart()]app: breakapp.tsx, fix it, the page comes back on its own in ~0.5s.Still broken with
nitro(). Nitro implementsdispatchFetch, sodevServer()steps aside and Nitro renders SSR errors itself using Youch. That page has no/@vite/clientand novite-error-overlay, so it has no HMR connection and qualifies for neither of Vite's recovery paths. Fix the file and nothing reaches the browser. Same app, only difference isnitro()in the plugin list.Fix belongs in Nitro. I tried patching the
src/runtime/internal/error/dev.tslocally to append a Vite client + reload script to the HTML error page, removed all SolidStart-side changes, and the Nitro setup recovered in ~0.5s. So an upstream fix is sufficient on its own.Leaving this open to track until that lands.
birkskyum commentedon Jul 27, 2026
The exact patch i applied to nitro is in
src/runtime/internal/error/dev.ts:83-96, whereWith
VITE_DEV_RECOVERY_SCRIPTbeing:birkskyum commentedon Jul 27, 2026
Cross-linking a sibling case that turned up while looking at this: #2260.
The report here is the eager path.
app.tsxis imported eagerly, so a syntax error fails at handler level and you get an error page (Nitro's youch page, per the patch above). Route modules take a different path: they all go throughlazy(), and there a syntax error produces no page at all. Solid's server-sidelazyhas no rejection handler, so the Suspense boundary never settles andrenderToStreamnever callsend(). The shell is flushed and the connection then stays open indefinitely, so the browser shows a blank page and no overlay, because as far as it's concerned the page loaded fine.Root cause is upstream in Solid: solidjs/solid#2945. Tracked on the Start side in #2260, where there's a local workaround in
withAssetsthat can be dropped once the Solid fix lands.birkskyum commentedon Aug 17, 2026
Retested on 2026-08-18 with:
@solidjs/start@2.0.0nitro@3.0.260610-beta(the current npmlatest)solid-js@1.9.15vite@8.2.1The status is unchanged for the eager
app.tsxpath whennitro()is installed:src/app.tsxnavigates the browser to Nitro's HTTP 500 / Youch page.The published Nitro package still returns only
await youch.toHTML(...)for an HTML development error response. I also checked current Nitromainat 4bfb35a; the same handler still has no/@vite/clientor equivalent recovery hook. I could not find a matching Nitro issue or PR implementing recovery.The separate lazy-route failure tracked in #2260 / solidjs/solid#2945 is now fixed by
solid-js@1.9.15and #2260 has been closed. That fix does not affect this eager handler-level error path.Conclusion: keep this issue open. Updating Solid is not sufficient; the remaining blocker is still Nitro's development error page needing a Vite/HMR recovery mechanism (or equivalent polling/reload behavior).
lxsmnsyc commentedon Oct 13, 2026
Checked this on the 1.x line, since the original report is against v1 on Vinxi. The comments above cover v2.
It still reproduces on 1.x. I used the
barefixture from the1.xbranch (vinxi 0.5.8) and followed the steps from the report in a browser:src/app.tsxinvalid. The browser ends up on a503 Server Unavailablepage with no error overlay.Cause. The 503 page is Vinxi's dev error handler (
vinxi/lib/dev-error.js). A syntax error inapp.tsxmakesssrLoadModulefail on the SSR handler's module graph (entry-server→StartServer→app.tsx), so none of SolidStart's runtime code runs. Vinxi then sends a static HTML page without/@vite/client. The page has no HMR connection, so nothing tells it when the file is fixed.Why SolidStart 1.x cannot fix this cleanly.
devErrorHandleroption (the line that would read it is commented out invinxi/lib/nitro-dev.js), so SolidStart cannot replace the error page through config.entry-serverdynamically and renders its own recovery page. That changes how 1.x loads its handler, which is too large a change for the maintenance line to work around a Vinxi bug.The fix belongs in Vinxi's dev error page: it needs a Vite client, or a reload-when-the-server-recovers script like the one in the Nitro patch above. In v2 SolidStart owns the dev server, which is why the no-Nitro case could be fixed there.
Workaround on 1.x: after fixing the file, reload the page by hand.