Add option to disable OSC 8 hyperlink emission (FORCE_HYPERLINK ignored) — ctrl-click opens duplicate tabs in Konsole
What happened
Since the newer TUI began emitting OSC 8 hyperlink escape sequences for URLs, ctrl-clicking a link in KDE Konsole opens two browser tabs for a single click.
Root cause (verified)
Konsole has its own regex-based URL detector (Settings → Edit Current Profile → Mouse → "Underline links") in addition to honoring OSC 8 hyperlinks. When Claude Code wraps a URL in an OSC 8 sequence whose visible text is also a valid URL, a single ctrl-click fires both Konsole handlers — the OSC 8 hyperlink and the regex match — so two tabs open.
Verified by isolating the handlers:
- Uncheck Konsole's "Underline links" → single tab (but the underline is lost). This proves the regex filter is the second handler.
- Re-check "Underline links" → two tabs again.
FORCE_HYPERLINK=0 does not disable emission
The supports-hyperlinks convention suggests FORCE_HYPERLINK=0 should disable OSC 8 emission, but it has no effect in Claude Code:
- Set
export FORCE_HYPERLINK=0in the shell, launchedclaudefrom that shell. - Confirmed inside the running session that the variable is inherited (
echo $FORCE_HYPERLINK→0). - Links still open two tabs — Claude Code still emits OSC 8.
So there is currently no way to disable OSC 8 hyperlink emission, and no combination of terminal + Claude Code settings yields both an underline (from the terminal's own filter) and a single-tab open.
Request
Please honor FORCE_HYPERLINK=0 (and/or add a settings.json option or CLI flag) to disable OSC 8 hyperlink emission and fall back to plain-text URLs. That lets terminals with their own URL detection (Konsole, and others with regex link filters) handle links as they did before the OSC 8 change.
Environment
- Claude Code: newer TUI (OSC 8 hyperlinks enabled)
- Terminal: KDE Konsole on Linux (Fedora),
TERM=xterm - This is not the JetBrains duplicate-mouse-event issue (#68568) — it reproduces in Konsole, a standard terminal.
3 Comments
Still reproduces on Claude Code 2.1.231 / Konsole 25.12.3. Process-level tracing places the second open elsewhere than the original diagnosis: it is spawned by Claude Code, not by Konsole.
Environment
KONSOLE_VERSION=251203), Wayland session,TERM=xterm-256color~/.local/share/konsole/has no.profile), so stock defaults including "Underline links"google-chrome.desktop, single handler in~/.config/mimeapps.listOne ctrl+click produces two independent process trees
Sampling
/procwhile ctrl+clicking a single link:The first tree is Konsole's link activation through KIO, which on Plasma launches the browser in a systemd user scope. Its parent is
systemd --user, notclaude. The second isxdg-openspawned by theclaudeprocess, thenkde-open.PID ordering (2545570 < 2545862) shows the systemd-launched Chrome was created before Claude Code's
xdg-openexisted, so it is not a descendant of that chain.Isolation tests
Each path on its own opens one tab:
| Test | Bypasses | Result |
|---|---|---|
|
google-chrome-stable <url>from a shell | Konsole + Claude Code | 1 tab ||
xdg-open <url>from a shell | Konsole + Claude Code | 1 tab ||
printf 'https://example.com/x\n'in a plain Konsole tab, ctrl+click | Claude Code | 1 tab || ctrl+click a link inside Claude Code's TUI | nothing | 2 tabs |
Chrome's history DB records two independent external launches rather than one launch that duplicated a tab: both rows have transition core type 6 (
START_PAGE, URL passed on the command line), 174 ms / 251 ms / 649 ms apart across three reproductions.Plain click opens nothing and shift+click opens nothing. Both handlers are bound to ctrl+click, so they fire together, matching what #82078 reports.
Correction to the original diagnosis
The original post attributes the second tab to Konsole honouring the OSC 8 hyperlink in addition to its own regex filter. That does not hold here.
This emits an OSC 8 hyperlink whose visible text contains no URL. In Konsole it renders as plain
CLICK-C, shows no underline on ctrl+hover, and is not clickable, so no OSC 8 hotspot is created. The probe usesESC \as the string terminator; the BEL-terminated form was not tested.The profile UI shows the same state: Konsole's Mouse tab has an "Allow escape sequences for links" checkbox (
AllowEscapedLinks), unchecked by default, which is the setting on this machine. With it off, the only hotspot Konsole contributes is the regex one behind "Underline links".What the process evidence leaves is the root cause #82078 identified from the binary: Claude Code's internal
onHyperlinkClickdispatcher spawnsxdg-openfor allowlisted schemes while the terminal independently activates the link. Konsole is one more environment for it, alongside gnome-terminal (#82078), Windows Terminal/WSL2 (#81905) and WSL (#73968). #82078 proposes gating internal dispatch on the same terminal-capability check that already gates OSC 8 emission.Workaround
The original post states there is no user-side workaround. One exists as of 2.1.195:
With it set, re-running the process sampler shows only the systemd-scoped Chrome, the
claude→xdg-openchain is gone, and one tab opens. Posted by @CluelessArchitect in #68568 on 2026-08-07, who notes it takes effect on restart.It disables click, drag and hover in fullscreen mode, so drag-selection inside the TUI stops working and shift+drag falls back to the terminal's native selection. @joshp-aferry reports the same trade-off in #68568.
FORCE_HYPERLINK=0was not tested here.---
Diagnosis performed by Claude Code on the affected machine (process sampling, binary inspection, Chrome history query), reviewed and posted by the account owner.
Thanks for the detailed report and the Konsole handler isolation — that was really helpful.
I tried to reproduce this on the current release 2.1.233 (Linux,
TERM=xterm, Konsole-style environment), capturing the raw terminal byte stream:FORCE_HYPERLINK=0set in the shell before launchingclaude, zero OSC 8 sequences were emitted — links render as plain text, so only Konsole's own regex link handler fires and ctrl-click opens a single tab.FORCE_HYPERLINK=1, OSC 8 emission returns.So
FORCE_HYPERLINK=0is now honored as a full off switch for OSC 8 emission — this was fixed in a recent release (changelog), and the variable is documented at https://code.claude.com/docs/en/env-vars (note: it reads a number, so only0disables).Closing as fixed — if you still see OSC 8 emitted with
FORCE_HYPERLINK=0on 2.1.233 or later, please reply with your version and we'll reopen.🤖 Generated with Claude Code
Re-tested on 2.1.251.
FORCE_HYPERLINK=0does remove OSC 8 emission, but not the duplicate open: with it set and Konsole's "Underline links" on, one ctrl+click still produces two process trees, one from Konsole through KIO and one fromclaudecallingxdg-open. The in-app dispatch is independent of emission, so turning emission off does not turn it off.This matches the mechanism confirmed in #76022 on 2026-08-17, which is open and marked
reproduced. Full isolation runs are posted there. The workaround that works here is/tui default.---
🤖 Generated with Claude Code