Before submitting
Area
apps/desktop
Steps to reproduce
-
Run T3 Code Desktop on Windows with a WSL environment/backend selected.
-
Inside WSL, start a server that listens only on loopback:
python3 -m http.server 8000 --bind 127.0.0.1
-
Confirm http://localhost:8000/ works from a normal Windows browser through WSL localhost forwarding.
-
Open T3 Code's built-in preview browser.
-
Enter http://localhost:8000/ or http://127.0.0.1:8000/ in the preview address bar.
-
Repeat with an HTTPS loopback URL such as https://localhost:8000/ when using a local HTTPS development server.
Expected behavior
A URL entered in the preview address bar should retain its requested origin. In particular:
http://localhost:8000/ should remain http://localhost:8000/.
http://127.0.0.1:8000/ should remain http://127.0.0.1:8000/.
https://localhost:8000/ should remain https://localhost:8000/.
Environment-relative port navigation may translate hosts when explicitly requested, but manually entered direct URLs should not silently change origin.
Actual behavior
The preview address bar rewrites loopback URLs to the active WSL environment's private eth0 address before Electron loads them. On the affected machine, the current WSL address was 172.25.85.75:
http://localhost:8000/ -> http://172.25.85.75:8000/
http://127.0.0.1:8000/ -> http://172.25.85.75:8000/
https://localhost:8000/ -> https://172.25.85.75:8000/
This is a client-side URL substitution rather than an HTTP redirect: the loopback server returns 200 without a Location header, and direct navigation to localhost does not change the hostname.
A server bound only to 127.0.0.1 becomes unreachable through the substituted WSL address. HTTPS development servers can additionally fail certificate validation because a certificate for localhost does not cover the WSL IP. The origin change can also affect cookies, CORS, allowed-host checks, and OAuth callback URLs.
The behavior is deterministic in the shipped source:
apps/server/src/components/preview/PreviewView.tsx sends every address-bar submission through resolveDiscoveredServerUrl().
apps/server/src/browser/browserTargetResolver.ts turns any recognized loopback URL into an environment-port target when the environment connection host is non-loopback.
- The environment-port resolver replaces the requested hostname with the hostname from
connection.httpBaseUrl while preserving protocol, port, path, query, and hash.
apps/server/src/preview/PortScanner.ts normalizes both loopback-only and wildcard listeners to localhost, discarding the bind scope needed to determine whether the WSL IP is reachable.
The browser target interface already distinguishes { kind: "url" } from { kind: "environment-port" }. Address-bar submissions appear to be using the discovered/environment-port behavior even though they are direct URL requests.
Impact
Major degradation or frequent failure
Version or commit
T3 Code desktop 0.0.29-nightly.20260712.791; the same behavior was initially reproduced on 0.0.28.
Environment
Windows 10.0.26200.8655, WSL2 kernel 6.6.87.2-microsoft-standard-WSL2, Ubuntu 24.04, x86_64.
Logs or stack traces
$ hostname -I
172.25.85.75 10.0.0.4 172.19.0.1 172.17.0.1 172.18.0.1
$ curl -I http://localhost:8000/
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.12.3
# No Location header
# T3 preview environment-port resolution, changing only protocol:
protocol=http -> http://172.25.85.75:8000/
protocol=https -> https://172.25.85.75:8000/
Screenshots, recordings, or supporting files
No attachment. The final URL shown in the preview address bar and the deterministic resolver behavior above capture the failure.
Workaround
Open the original localhost URL in a normal Windows browser.
For HTTP-only development, binding the server to 0.0.0.0 can make it reachable through the substituted WSL IP, but this broadens exposure and does not solve HTTPS origin/certificate problems.
A focused product fix would treat address-bar submissions as direct { kind: "url" } navigation and reserve { kind: "environment-port" } translation for discovered local-server cards or other explicitly environment-relative navigation.
Before submitting
Area
apps/desktop
Steps to reproduce
Run T3 Code Desktop on Windows with a WSL environment/backend selected.
Inside WSL, start a server that listens only on loopback:
Confirm
http://localhost:8000/works from a normal Windows browser through WSL localhost forwarding.Open T3 Code's built-in preview browser.
Enter
http://localhost:8000/orhttp://127.0.0.1:8000/in the preview address bar.Repeat with an HTTPS loopback URL such as
https://localhost:8000/when using a local HTTPS development server.Expected behavior
A URL entered in the preview address bar should retain its requested origin. In particular:
http://localhost:8000/should remainhttp://localhost:8000/.http://127.0.0.1:8000/should remainhttp://127.0.0.1:8000/.https://localhost:8000/should remainhttps://localhost:8000/.Environment-relative port navigation may translate hosts when explicitly requested, but manually entered direct URLs should not silently change origin.
Actual behavior
The preview address bar rewrites loopback URLs to the active WSL environment's private
eth0address before Electron loads them. On the affected machine, the current WSL address was172.25.85.75:This is a client-side URL substitution rather than an HTTP redirect: the loopback server returns
200without aLocationheader, and direct navigation to localhost does not change the hostname.A server bound only to
127.0.0.1becomes unreachable through the substituted WSL address. HTTPS development servers can additionally fail certificate validation because a certificate forlocalhostdoes not cover the WSL IP. The origin change can also affect cookies, CORS, allowed-host checks, and OAuth callback URLs.The behavior is deterministic in the shipped source:
apps/server/src/components/preview/PreviewView.tsxsends every address-bar submission throughresolveDiscoveredServerUrl().apps/server/src/browser/browserTargetResolver.tsturns any recognized loopback URL into anenvironment-porttarget when the environment connection host is non-loopback.connection.httpBaseUrlwhile preserving protocol, port, path, query, and hash.apps/server/src/preview/PortScanner.tsnormalizes both loopback-only and wildcard listeners tolocalhost, discarding the bind scope needed to determine whether the WSL IP is reachable.The browser target interface already distinguishes
{ kind: "url" }from{ kind: "environment-port" }. Address-bar submissions appear to be using the discovered/environment-port behavior even though they are direct URL requests.Impact
Major degradation or frequent failure
Version or commit
T3 Code desktop
0.0.29-nightly.20260712.791; the same behavior was initially reproduced on0.0.28.Environment
Windows
10.0.26200.8655, WSL2 kernel6.6.87.2-microsoft-standard-WSL2, Ubuntu 24.04, x86_64.Logs or stack traces
Screenshots, recordings, or supporting files
No attachment. The final URL shown in the preview address bar and the deterministic resolver behavior above capture the failure.
Workaround
Open the original localhost URL in a normal Windows browser.
For HTTP-only development, binding the server to
0.0.0.0can make it reachable through the substituted WSL IP, but this broadens exposure and does not solve HTTPS origin/certificate problems.A focused product fix would treat address-bar submissions as direct
{ kind: "url" }navigation and reserve{ kind: "environment-port" }translation for discovered local-server cards or other explicitly environment-relative navigation.