Environment
- OS: WSL2 (Ubuntu) connecting to Chrome on Windows host
- Chrome: 146.0.7680.178 (Windows)
- Node.js: v24.14.1
- web-access: 2.4.2
- Chrome launch:
--remote-debugging-port=9222 --user-data-dir=D:\ChromeDebugProfile
Problem
CDP Proxy repeatedly fails with 连接错误: 连接失败 when running in WSL2.
Root cause: In WSL2, discoverChromePort() in cdp-proxy.mjs cannot find the DevToolsActivePort file because:
- The Linux paths (
~/.config/google-chrome/DevToolsActivePort) don't exist — Chrome runs on Windows
- The
win32 paths aren't checked because os.platform() returns linux in WSL
So it falls through to port scanning, which finds port 9222 but returns { port, wsPath: null }. Then getWebSocketUrl() builds ws://127.0.0.1:9222/devtools/browser without a UUID.
Modern Chrome (tested on 146) rejects WebSocket connections without the browser UUID in the path — resulting in a 1006 close code.
Reproduction
# In WSL2, with Chrome remote debugging on Windows:
# This fails (no UUID):
node -e "const ws = new WebSocket('ws://127.0.0.1:9222/devtools/browser'); ws.onerror = e => console.log('FAIL', e.type); ws.onclose = e => console.log('code', e.code)"
# → FAIL error, code 1006
# This works (with UUID):
node -e "fetch('http://127.0.0.1:9222/json/version').then(r=>r.json()).then(j=>{const ws = new WebSocket(j.webSocketDebuggerUrl); ws.onopen = () => console.log('OK')})"
# → OK
Suggested Fix
After port scanning succeeds, fetch the UUID via HTTP API before returning:
// In discoverChromePort(), the port scanning fallback section:
for (const port of commonPorts) {
const ok = await checkPort(port);
if (ok) {
console.log(`[CDP Proxy] 扫描发现 Chrome 调试端口: ${port}`);
// Fetch UUID-bearing wsPath from HTTP API (required by modern Chrome)
let wsPath = null;
try {
const resp = await fetch(`http://127.0.0.1:${port}/json/version`);
const info = await resp.json();
if (info.webSocketDebuggerUrl) {
const url = new URL(info.webSocketDebuggerUrl);
wsPath = url.pathname;
}
} catch (e) { /* fall through with null wsPath */ }
return { port, wsPath };
}
}
This is a minimal, non-breaking change — it only adds a /json/version HTTP call (not a WebSocket, so it won't trigger Chrome's authorization popup) as a fallback when DevToolsActivePort is unavailable.
Notes
- The
/json/version endpoint is a standard Chrome DevTools Protocol HTTP API, available whenever remote debugging is active
- This fix also benefits any Linux environment where Chrome is started with
--remote-debugging-port but DevToolsActivePort is missing or inaccessible
- The
check-deps.mjs script has the same DevToolsActivePort path limitation for WSL2, though it only affects port detection (not the connection failure)
Environment
--remote-debugging-port=9222 --user-data-dir=D:\ChromeDebugProfileProblem
CDP Proxy repeatedly fails with
连接错误: 连接失败when running in WSL2.Root cause: In WSL2,
discoverChromePort()incdp-proxy.mjscannot find theDevToolsActivePortfile because:~/.config/google-chrome/DevToolsActivePort) don't exist — Chrome runs on Windowswin32paths aren't checked becauseos.platform()returnslinuxin WSLSo it falls through to port scanning, which finds port 9222 but returns
{ port, wsPath: null }. ThengetWebSocketUrl()buildsws://127.0.0.1:9222/devtools/browserwithout a UUID.Modern Chrome (tested on 146) rejects WebSocket connections without the browser UUID in the path — resulting in a
1006close code.Reproduction
Suggested Fix
After port scanning succeeds, fetch the UUID via HTTP API before returning:
This is a minimal, non-breaking change — it only adds a
/json/versionHTTP call (not a WebSocket, so it won't trigger Chrome's authorization popup) as a fallback whenDevToolsActivePortis unavailable.Notes
/json/versionendpoint is a standard Chrome DevTools Protocol HTTP API, available whenever remote debugging is active--remote-debugging-portbutDevToolsActivePortis missing or inaccessiblecheck-deps.mjsscript has the sameDevToolsActivePortpath limitation for WSL2, though it only affects port detection (not the connection failure)