[Bug]: Web client init dies after /.well-known/t3/environment on Chrome 150 — environment stuck "Offline" (works on Chromium 148 / Safari)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
Description
What happened
After Chrome auto-updated to 150.0.7871.129 (macOS), the T3 Code web client can no longer connect to a self-hosted headless environment. Every tab shows the environment banner "Offline — Reconnect this environment before sending messages or running actions", and clicking Reconnect does nothing. In a fresh profile (incognito) the app renders a blank shell ("No projects yet", empty thread pane).
The same server, reached the same way, works perfectly at the same time from:
- Safari (current macOS release) — pairs and connects instantly
- Chromium 148 (an Electron 42 embedded browser) — pairs and connects instantly
So the regression tracks the browser engine version, not the server or network.
Setup
- Server:
t30.0.28 (npm global install) running headless via systemd on Ubuntu,T3CODE_MODE=web - Also reproduced on 0.0.29-nightly.20260721.864 (identical behavior)
- Client access: SSH local port-forward, page served at
http://localhost:3773 - Auth: one-time pairing tokens (
t3 auth pairing create), no T3 Connect relay
Evidence
With T3CODE_LOG_LEVEL=debug, a healthy client's request sequence after page load is:
GET /api/auth/session 200
GET /.well-known/t3/environment 200
GET /assets/pierre-light-*.js 200
GET /assets/pierre-dark-*.js 200
GET /assets/worker-*.js 200 (×5)
→ persistent WebSocket established
Chrome 150 stops dead after /.well-known/t3/environment — it never requests the theme chunks or the worker scripts, and never attempts the WebSocket. At the TCP level Chrome holds no persistent connection to the server (all sockets close right after static assets), and t3 auth session list shows the freshly-paired Chrome sessions as last connected: never — pairing itself succeeds, the link connection is never attempted.
The browser console shows this at startup (visible on the working Chromium 148 client too, where it is apparently non-fatal):
Clerk: Production Keys are only allowed for domain "t3.codes".
API Error: The Request HTTP Origin header must be equal to or a subdomain of the requesting URL.
at ... clerk.browser.js ...
at async e.getEntryChunks (http://localhost:3773/assets/index-C0HqD506.js:16:73635)
getEntryChunks appears to await Clerk's load; the bundled production Clerk key is domain-locked to t3.codes, so it always rejects a localhost-served self-hosted deployment. My working hypothesis is that this rejection was previously survivable (the client fell back to local pairing auth), and something in Chrome 150 makes the failure fatal during init — killing chunk loading before the environment link layer ever starts. I could not capture the exact fatal exception in Chrome itself, but the request trace above pins where init dies.
Reproduction
- Self-host
t30.0.28 headless (T3CODE_MODE=web) on a remote box; access it via SSH tunnel athttp://localhost:3773 - Pair via
t3 auth pairing createlink in Chrome 150.0.7871.129 (macOS) — pairing succeeds - Open any thread → environment banner shows Offline; Reconnect no-ops; fresh profile shows blank shell
- Repeat in Safari or an older Chromium → connects immediately
Expected
The web client should connect from current Chrome, and a Clerk key rejection on non-t3.codes origins should never block init for self-hosted/localhost deployments.
Workaround
Use Safari (or any non-Chromium-150 browser) against the same server — fully functional.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing client startup around getEntryChunks in assets/index-C0HqD506.js and compare the Chrome 150 request sequence with Chromium 148. Determine why the Clerk origin rejection prevents later theme and worker requests, then verify that a localhost deployment reaches the persistent WebSocket without blocking on Clerk initialization.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- authentication, frontend, web-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 42/100