Skip to content

Fix #49: Serve UI JavaScript with correct MIME type on Windows - #262

Open
arkaccess wants to merge 1 commit into
AutoForgeAI:masterfrom
arkaccess:swarm/issue-49-dennis
Open

arkaccess wants to merge 1 commit into
AutoForgeAI:masterfrom
arkaccess:swarm/issue-49-dennis

Conversation

@arkaccess

Copy link
Copy Markdown

Closes #49

Problem

On some Windows machines the UI loads as a blank page with Failed to load module script ... MIME type of "text/plain". Python's mimetypes module seeds itself from the Windows registry (HKEY_CLASSES_ROOT\.js\Content Type), which editors/tools often set to text/plain. Starlette's StaticFiles/FileResponse use mimetypes.guess_type, so the Vite bundle gets served as text/plain and the browser rejects it.

Fix

server/main.py now calls mimetypes.add_type(...) at import time for .js, .mjs, .css, .svg, .json, .wasm. add_type initializes the database (including the registry) first and then overrides, so these mappings always win regardless of registry contents.

Verification

  • Added test_static_mime.py: simulates a poisoned registry (.js/.css → text/plain), imports server.main, and checks both guess_type and an actual StaticFiles response Content-Type. Fails on master (2 failed), passes with this change (2 passed).
  • ruff check . clean; python test_security.py passes.
  • Not tested on real Windows (Linux box); the registry mapping is simulated instead.

Assumptions

  • Uses text/javascript (current WHATWG / RFC 9239 recommendation) rather than application/javascript; browsers accept either.

🤖 Generated with Claude Code

Python's mimetypes reads the Windows registry, where .js is often mapped
to text/plain. Starlette then serves the Vite bundle with the wrong
Content-Type, browsers refuse to run the module script, and the UI is a
blank page. Register explicit mappings at server import so they win over
the registry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@zwanski-start

Copy link
Copy Markdown

🔍 QA report: ✅ Passed

Tester: Barbara (cubefarm agent, in a fresh session) · Round: 1 · Author: Dennis

The PR sets the MIME types for .js, .mjs, .css, .svg, .json and .wasm in server/main.py when the server starts, overriding whatever the Windows registry says. With a simulated bad registry, master already served .js correctly (settings.py forces it) but sent CSS and SVG as text/plain. With the PR every UI file has the right Content-Type and the app renders with no console errors. Lint, build and the new tests pass; the only failing tests also fail on master. Tested on Linux with a fake registry, not on real Windows.

Check Details
✅ Issue #49 repro: assets served with correct MIME under a bad registry (real uvicorn) Ran the server through a launcher that patches mimetypes so .js/.css/.svg map to text/plain, the same way a bad Windows registry entry would. Master: .js text/javascript (already forced in server/routers/settings.py), .css text/plain, /vite.svg text/plain. PR: .js text/javascript, .css text/css, /vite.svg image/svg+xml, / text/html.
✅ Browser render under the bad registry Loaded http://127.0.0.1:5443/ in Playwright. The app rendered (#root filled, styles applied) with 0 console errors or warnings. Fetching every script, modulepreload and stylesheet on the page showed text/javascript for all 7 JS chunks and text/css for the CSS.
✅ Phone-width layout Resized to 390x844. The page renders with no errors and the layout matches master, since the PR has no UI changes.
✅ New regression test fails on master and passes on PR test_static_mime.py: 2 failed on master, 2 passed on the PR branch.
✅ REST routes still work /api/projects 200, /api/health 200, /api/settings 200, unknown project 404.
✅ No regressions in pytest / mypy Full pytest: 21 failures in test_devserver_security.py, the same 21 fail on master. mypy: 26 errors vs 25 on master; the extra one is in venv/bin/activate_this.py (only present because this worktree has a venv), none in server/main.py.
✅ Security / code review No changes to security.py or the localhost middleware. The MIME settings run before the StaticFiles mount and SPA FileResponse routes. No hardcoded paths, no debug leftovers. One harmless leftover: the .js override in settings.py from master is now redundant.
⏭️ UI Playwright e2e The PR touches no UI code.
🧪 Commands run
Command Result
ruff check . All checks passed
mypy . 26 errors (25 on master; the extra one is in venv/bin/activate_this.py, not PR code)
python -m pytest test_static_mime.py PR: 2 passed; master: 2 failed
python test_security.py ALL TESTS PASSED
python -m pytest -q PR: 21 failed, 146 passed; master: 21 failed (same tests) + the 2 new tests
npm --prefix ui run build success
npm --prefix ui run lint 0 errors, 6 warnings (already on master)
uvicorn server.main:app on port 5443 with simulated bad registry, curl -D - on /, /assets/*.js, /assets/*.css, /vite.svg (master vs PR) Master: CSS and SVG text/plain; PR: all correct

No browser screenshots were taken in this round.

Posted by cubefarm · merges automatically once GitHub's checks pass

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.

Windows - javascript error (blank web page) after start_ui.bat clean install

2 participants