Skip to content

fix: vite dynamic import fix#1097

Open
Bl3f wants to merge 1 commit into
mainfrom
fix/vite-dynamic-import
Open

fix: vite dynamic import fix#1097
Bl3f wants to merge 1 commit into
mainfrom
fix/vite-dynamic-import

Conversation

@Bl3f

@Bl3f Bl3f commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Review in cubic

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

🚀 Preview Deployment

URL https://pr-1097-bc6a56a.preview.getnao.io
Commit bc6a56a

⚠️ No LLM API keys configured - you'll see the API key setup flow when trying to chat.


Preview will be automatically removed when this PR is closed.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 issues found across 4 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/frontend/src/main.tsx">

<violation number="1" location="apps/frontend/src/main.tsx:42">
P2: Both the Vite preload error handler here and the `RouterError` component rely on the same `sessionStorage` key (`nao:chunk-error-reloaded`) to coordinate reload-loop prevention, but the key is duplicated rather than shared. `RouterError` keeps it in a local `RELOAD_FLAG` constant, while `main.tsx` hardcodes it in three places. If the two ever drift, the recovery paths will stop recognizing each other and can reintroduce repeated reloads. Consider exporting `RELOAD_FLAG` from `router-error.tsx` (or a shared constant) and reusing it here, since `main.tsx` already imports `RouterError` from that module.</violation>

<violation number="2" location="apps/frontend/src/main.tsx:42">
P2: The `vite:preloadError` handler should call `event.preventDefault()` before reloading or returning to stop the original import error from propagating. Per the Vite docs, if `preventDefault()` is not called, the error is still thrown. Currently the handler doesn't accept the event parameter, so the error can propagate into TanStack Router's `defaultErrorComponent` (briefly showing `RouterError`) before the reload completes, and on guarded subsequent events the error is thrown unhandled. Consider adding the event parameter and calling `event.preventDefault()` in both the guard-return path and before `window.location.reload()`.</violation>

<violation number="3" location="apps/frontend/src/main.tsx:42">
P2: The new `vite:preloadError` handler and the `setTimeout` cleanup directly access `sessionStorage` without `try/catch` guards. In browsers or embedded contexts where storage is blocked or sandboxed, these calls can throw a `SecurityError`, which would abort the recovery reload and leave an unhandled exception from the timeout. The project already handles this correctly in `router-error.tsx` (e.g., `hasReloadedForChunkError` wraps `sessionStorage.getItem` in `try/catch`), so the same guard should be applied here for consistent error recovery.</violation>
</file>

<file name="apps/frontend/src/components/router-error.tsx">

<violation number="1" location="apps/frontend/src/components/router-error.tsx:28">
P1: The error fallback UI directly accesses `error.message`, but TanStack Router passes the raw thrown value to `ErrorComponentProps`, which can be a string, object, or primitive rather than an `Error` instance. If a non-Error value reaches this component, the render will throw at runtime. Use the same normalization pattern already present in `isChunkLoadError` — for example, render the message as `error instanceof Error ? error.message : String(error)` — so the UI remains safe regardless of what the route or loader throws.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

<div className='flex h-full flex-1 flex-col items-center justify-center gap-4 p-6 text-center'>
<div className='max-w-md space-y-2'>
<h2 className='text-lg font-medium'>Something went wrong</h2>
<p className='text-sm text-muted-foreground'>{error.message}</p>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The error fallback UI directly accesses error.message, but TanStack Router passes the raw thrown value to ErrorComponentProps, which can be a string, object, or primitive rather than an Error instance. If a non-Error value reaches this component, the render will throw at runtime. Use the same normalization pattern already present in isChunkLoadError — for example, render the message as error instanceof Error ? error.message : String(error) — so the UI remains safe regardless of what the route or loader throws.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/frontend/src/components/router-error.tsx, line 28:

<comment>The error fallback UI directly accesses `error.message`, but TanStack Router passes the raw thrown value to `ErrorComponentProps`, which can be a string, object, or primitive rather than an `Error` instance. If a non-Error value reaches this component, the render will throw at runtime. Use the same normalization pattern already present in `isChunkLoadError` — for example, render the message as `error instanceof Error ? error.message : String(error)` — so the UI remains safe regardless of what the route or loader throws.</comment>

<file context>
@@ -0,0 +1,85 @@
+		<div className='flex h-full flex-1 flex-col items-center justify-center gap-4 p-6 text-center'>
+			<div className='max-w-md space-y-2'>
+				<h2 className='text-lg font-medium'>Something went wrong</h2>
+				<p className='text-sm text-muted-foreground'>{error.message}</p>
+			</div>
+			<div className='flex gap-2'>
</file context>
Suggested change
<p className='text-sm text-muted-foreground'>{error.message}</p>
<p className='text-sm text-muted-foreground'>{error instanceof Error ? error.message : String(error)}</p>

defaultErrorComponent: RouterError,
});

window.addEventListener('vite:preloadError', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Both the Vite preload error handler here and the RouterError component rely on the same sessionStorage key (nao:chunk-error-reloaded) to coordinate reload-loop prevention, but the key is duplicated rather than shared. RouterError keeps it in a local RELOAD_FLAG constant, while main.tsx hardcodes it in three places. If the two ever drift, the recovery paths will stop recognizing each other and can reintroduce repeated reloads. Consider exporting RELOAD_FLAG from router-error.tsx (or a shared constant) and reusing it here, since main.tsx already imports RouterError from that module.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/frontend/src/main.tsx, line 42:

<comment>Both the Vite preload error handler here and the `RouterError` component rely on the same `sessionStorage` key (`nao:chunk-error-reloaded`) to coordinate reload-loop prevention, but the key is duplicated rather than shared. `RouterError` keeps it in a local `RELOAD_FLAG` constant, while `main.tsx` hardcodes it in three places. If the two ever drift, the recovery paths will stop recognizing each other and can reintroduce repeated reloads. Consider exporting `RELOAD_FLAG` from `router-error.tsx` (or a shared constant) and reusing it here, since `main.tsx` already imports `RouterError` from that module.</comment>

<file context>
@@ -35,8 +36,19 @@ const router = createRouter({
+	defaultErrorComponent: RouterError,
 });
 
+window.addEventListener('vite:preloadError', () => {
+	if (sessionStorage.getItem('nao:chunk-error-reloaded') === '1') {
+		return;
</file context>

defaultErrorComponent: RouterError,
});

window.addEventListener('vite:preloadError', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The vite:preloadError handler should call event.preventDefault() before reloading or returning to stop the original import error from propagating. Per the Vite docs, if preventDefault() is not called, the error is still thrown. Currently the handler doesn't accept the event parameter, so the error can propagate into TanStack Router's defaultErrorComponent (briefly showing RouterError) before the reload completes, and on guarded subsequent events the error is thrown unhandled. Consider adding the event parameter and calling event.preventDefault() in both the guard-return path and before window.location.reload().

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/frontend/src/main.tsx, line 42:

<comment>The `vite:preloadError` handler should call `event.preventDefault()` before reloading or returning to stop the original import error from propagating. Per the Vite docs, if `preventDefault()` is not called, the error is still thrown. Currently the handler doesn't accept the event parameter, so the error can propagate into TanStack Router's `defaultErrorComponent` (briefly showing `RouterError`) before the reload completes, and on guarded subsequent events the error is thrown unhandled. Consider adding the event parameter and calling `event.preventDefault()` in both the guard-return path and before `window.location.reload()`.</comment>

<file context>
@@ -35,8 +36,19 @@ const router = createRouter({
+	defaultErrorComponent: RouterError,
 });
 
+window.addEventListener('vite:preloadError', () => {
+	if (sessionStorage.getItem('nao:chunk-error-reloaded') === '1') {
+		return;
</file context>

defaultErrorComponent: RouterError,
});

window.addEventListener('vite:preloadError', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The new vite:preloadError handler and the setTimeout cleanup directly access sessionStorage without try/catch guards. In browsers or embedded contexts where storage is blocked or sandboxed, these calls can throw a SecurityError, which would abort the recovery reload and leave an unhandled exception from the timeout. The project already handles this correctly in router-error.tsx (e.g., hasReloadedForChunkError wraps sessionStorage.getItem in try/catch), so the same guard should be applied here for consistent error recovery.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/frontend/src/main.tsx, line 42:

<comment>The new `vite:preloadError` handler and the `setTimeout` cleanup directly access `sessionStorage` without `try/catch` guards. In browsers or embedded contexts where storage is blocked or sandboxed, these calls can throw a `SecurityError`, which would abort the recovery reload and leave an unhandled exception from the timeout. The project already handles this correctly in `router-error.tsx` (e.g., `hasReloadedForChunkError` wraps `sessionStorage.getItem` in `try/catch`), so the same guard should be applied here for consistent error recovery.</comment>

<file context>
@@ -35,8 +36,19 @@ const router = createRouter({
+	defaultErrorComponent: RouterError,
 });
 
+window.addEventListener('vite:preloadError', () => {
+	if (sessionStorage.getItem('nao:chunk-error-reloaded') === '1') {
+		return;
</file context>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant