Links open twice on WSL: Claude Code opens via xdg-open (WSLg browser) in addition to the terminal
What happened
On WSL2 under Windows Terminal, a single URL from Claude Code opens twice:
one browser instance is launched by Claude Code itself, and a second by the
terminal when the OSC 8 hyperlink is clicked.
Before touching my WSL config, the two opens even landed in different browsers
— one in the in-WSL WSLg browser, one in the Windows browser — which is what
makes the two independent openers obvious.
Related to #41625 (Claude Code treats WSL like plain Linux when opening URLs),
but the user-visible symptom here is the double open, and there is a working
workaround, so filing separately.
Environment
- Claude Code:
2.1.199(single compiled binary install) - OS: WSL2, Ubuntu
- Terminal: Windows Terminal (
WT_SESSIONis set) BROWSERenv: unset by default
Steps to reproduce
- Run Claude Code inside WSL2 under Windows Terminal.
- Have it emit / open any URL (e.g. a login/OAuth link, or click a printed link).
- Observe two browser tabs opening for the one URL.
Expected
The link opens exactly once, in the Windows default browser.
Root cause (from inspecting the binary)
The bundled open library (cli-internal/node_modules/open/index.js appears in
the binary) takes the xdg-open branch on WSL rather than a WSL/cmd.exe
branch. The binary contains both xdg-open and cmd.exe code paths plus anisWsl / /proc/version check, but on my machine the xdg-open path is the one
that runs (URLs went to the WSLg browser, not Windows). So:
- Opener #1: Claude Code ->
xdg-open-> WSL default browser (WSLg). - Opener #2: Windows Terminal opens the same OSC 8 hyperlink on click -> Windows.
Reproduction condition
The second (Claude-side) open only fires when Claude Code's xdg-open call
resolves to a working x-scheme-handler/https handler — i.e. a Linux GUI browser
is installed and set as the xdg default, OR a forwarder like wslview is the
default. With no https handler configured at all, xdg-open opens nothing and
Claude's open silently no-ops (only the terminal opens the link). So "remove the
Linux browser" only avoids the double by disabling Claude's opener entirely — the
same trade-off as the BROWSER=/bin/true workaround below.
Workarounds
- Point WSL's default browser at
wslviewsoxdg-openforwards to Windows:
xdg-settings set default-web-browser wslview.desktop
— but this makes both opens land in Windows = two Windows tabs.
- This actually removes the double open: set
BROWSERto a no-op in
settings.json, since Claude Code honors process.env.BROWSER:
``json``
{ "env": { "BROWSER": "/bin/true" } }
Claude Code's own open becomes a no-op, leaving only the terminal to open the
link once. Trade-off: Claude no longer auto-opens its own URLs (login/OAuth) —
you click the printed link instead.
Suggested fix
In the WSL case, either use the Windows browser directly (as proposed in #41625)
or honor process.env.BROWSER — and avoid opening a URL that the terminal will
also open via its OSC 8 hyperlink, to prevent the double launch.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗