Vite inline script in index.html causes Failed to parse JSON file error with Express middleware mode + Chromium DevTools
Using the recommended Vite setup (inline <script type="module"> in index.html) causes:
Pre-transform error: Failed to parse JSON file.
when:
- Vite runs in Express middleware mode
- DevTools is open
If the Vite logger is wired to a fatal handler (e.g. process.exit(1)), this crashes the dev server.
This is a common setup for projects ported over from Replit starter templates, which use Express as a host server with Vite middleware mode for development, so could affect a bunch of people
Steps to reproduce
- Create a Vite + Express app using middleware mode with a catch-all SPA handler that calls
vite.transformIndexHtml(url, template) for all unmatched routes
- Run
npx -y grab@latest init (adds inline <script type="module"> to index.html)
- Start the dev server
- Open
http://localhost:5000 in a chromium browser with DevTools open
- Server logs
Pre-transform error: Failed to parse JSON file.
Expected behavior
The dev server starts without errors regardless of whether Chromium DevTools is open.
Actual behavior
Pre-transform error: Failed to parse JSON file. appears in the server console within seconds of page load.
Debugging
To confirm this is the cause, add a console.error before the error throw in
node_modules/vite/dist/node/chunks/dep-*.js. Search for Failed to parse JSON file
and add a log line above it:
// Before:
this.error(Failed to parse JSON file + msg, position);
// After:
console.error([vite:json DEBUG] Failed file: ${id});
this.error(Failed to parse JSON file + msg, position);
You'll get something like what I got:
19:48:00 [vite] Pre-transform error: Failed to parse JSON file.
[vite:json DEBUG] Failed file: /.well-known/appspecific/com.chrome.devtools.json?html-proxy&index=0.js
Explanation
- DevTools automatically requests
/.well-known/appspecific/com.chrome.devtools.json
- The Express catch-all SPA handler serves
index.html for this request via vite.transformIndexHtml(url, template)
- Vite extracts the inline
<script type="module"> as an HTML proxy module, inheriting the parent URL: /.well-known/appspecific/com.chrome.devtools.json?html-proxy&index=0.js
- Vite's
vite:json plugin matches the .json extension in that URL and tries to parse the JavaScript proxy content as JSON
- Parsing fails → error
Suggested fix
Easy workaround: exclude /.well-known/* from the Express SPA fallback route
Add a note to the Vite instructions in the README for Express middleware mode setups, recommending importing from the entry file instead:
⚠️ Express middleware mode: If you're running Vite in Express middleware mode
(createServer({ middlewareMode: true })), which is common in Replit starter templates
and fullstack Express+React monorepos, the inline script approach can cause
Failed to parse JSON file errors when Chromium-based DevTools (Chrome, Edge, Brave, etc.)
are open. This happens because Chromium DevTools requests a .json URL that the Express
catch-all handler passes through vite.transformIndexHtml(), causing Vite to create an
HTML proxy module with .json in its URL.
For these setups, import react-grab from your entry file instead:
// src/main.tsx
if (import.meta.env.DEV) {
import("react-grab");
}
Vite inline script in
index.htmlcausesFailed to parse JSON fileerror with Express middleware mode + Chromium DevToolsUsing the recommended Vite setup (inline
<script type="module">inindex.html) causes:Pre-transform error: Failed to parse JSON file.
when:
If the Vite logger is wired to a fatal handler (e.g.
process.exit(1)), this crashes the dev server.This is a common setup for projects ported over from Replit starter templates, which use Express as a host server with Vite middleware mode for development, so could affect a bunch of people
Steps to reproduce
vite.transformIndexHtml(url, template)for all unmatched routesnpx -y grab@latest init(adds inline<script type="module">toindex.html)http://localhost:5000in a chromium browser with DevTools openPre-transform error: Failed to parse JSON file.Expected behavior
The dev server starts without errors regardless of whether Chromium DevTools is open.
Actual behavior
Pre-transform error: Failed to parse JSON file.appears in the server console within seconds of page load.Debugging
To confirm this is the cause, add a
console.errorbefore the error throw innode_modules/vite/dist/node/chunks/dep-*.js. Search forFailed to parse JSON fileand add a log line above it:
// Before:
this.error(
Failed to parse JSON file+ msg, position);// After:
console.error(
[vite:json DEBUG] Failed file: ${id});this.error(
Failed to parse JSON file+ msg, position);You'll get something like what I got:
Explanation
/.well-known/appspecific/com.chrome.devtools.jsonindex.htmlfor this request viavite.transformIndexHtml(url, template)<script type="module">as an HTML proxy module, inheriting the parent URL:/.well-known/appspecific/com.chrome.devtools.json?html-proxy&index=0.jsvite:jsonplugin matches the.jsonextension in that URL and tries to parse the JavaScript proxy content as JSONSuggested fix
Easy workaround: exclude
/.well-known/*from the Express SPA fallback routeAdd a note to the Vite instructions in the README for Express middleware mode setups, recommending importing from the entry file instead: