Skip to content

Vite inline script in index.html causes Failed to parse JSON file crash with Express middleware mode + Chromium DevTools #244

@learkonas

Description

@learkonas

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:

  1. Vite runs in Express middleware mode
  2. 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

  1. Create a Vite + Express app using middleware mode with a catch-all SPA handler that calls vite.transformIndexHtml(url, template) for all unmatched routes
  2. Run npx -y grab@latest init (adds inline <script type="module"> to index.html)
  3. Start the dev server
  4. Open http://localhost:5000 in a chromium browser with DevTools open
  5. 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

  1. DevTools automatically requests /.well-known/appspecific/com.chrome.devtools.json
  2. The Express catch-all SPA handler serves index.html for this request via vite.transformIndexHtml(url, template)
  3. 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
  4. Vite's vite:json plugin matches the .json extension in that URL and tries to parse the JavaScript proxy content as JSON
  5. 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");
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions