[BUG] OSC 8 hyperlinks in custom statusline broken inside tmux — rendering layer analysis
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
OSC 8 hyperlinks from custom statusline programs don't render as clickable links when Claude Code runs inside tmux. This is a re-report of #23438 (closed as stale/locked), now with root cause analysis.
Related issues: #21586, #19976, #14011
Root Cause: Claude Code renders its statusline output outside Ink's React component tree, writing directly to the terminal. Ink's rendering cycle erases and rewrites all managed terminal lines on every update. This destroys any OSC 8 hyperlinks that were written directly to stdout by external statusline programs.
Ink itself is not the problem. As of slice-ansi v8 and @alcalzone/ansi-tokenize v0.3+, Ink's character grid pipeline fully supports OSC 8 round-tripping. Hyperlinks that flow through the Ink React tree survive rendering. The issue is that statusline content bypasses this tree entirely.
Rendering pipeline walkthrough:
- External statusline program writes OSC 8 hyperlinks to stdout
- Ink's next render cycle calls
eraseLines()to clear previous output - Ink rewrites its grid-rendered content (which doesn't include the external hyperlinks)
- The hyperlink text appears but is no longer clickable — the OSC 8 sequences were erased
What Should Happen?
OSC 8 escape sequences from statusline programs should pass through Claude Code's rendering layer unchanged and render as clickable hyperlinks inside tmux, just as they do outside tmux.
Suggested fix: Route statusline content through the Ink component tree rather than writing it directly to the terminal:
- Render statusline output inside an Ink
<Text>node (preserving raw OSC 8 sequences) - Use Ink's
<Link>component for statusline hyperlinks - Ensure the statusline rendering region is excluded from Ink's
eraseLines()scope
This is a Claude Code change only — no upstream Ink changes are needed.
Error Messages/Logs
No error messages. The statusline text renders visually, but hyperlinks are not clickable. Verified with `xxd` that the statusline binary outputs correct OSC 8 escape sequences — they are simply erased by Ink's render cycle.
Evidence that tmux is not the issue:
- `printf '\033]8;;https://example.com\033\\Click\033]8;;\033\\\n'` in the same tmux pane renders as a clickable link
- Same statusline works when running Claude Code outside tmux
Steps to Reproduce
- Configure a custom statusline that outputs OSC 8 hyperlinks:
````
\033]8;;https://example.com\033\\link text\033]8;;\033\\
- Start tmux with
allow-passthrough onand hyperlinks enabled interminal-features - Run Claude Code inside tmux
- Observe that statusline hyperlinks are not clickable
Control tests (both pass):
- Run
printf '\033]8;;https://example.com\033\\Click\033]8;;\033\\\n'in the same tmux pane → clickable - Run Claude Code outside tmux with the same statusline → clickable
Environment: Claude Code 2.1.x, tmux 3.5a, Ghostty terminal, macOS
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.73
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
iTerm2
Additional Information
_No response_
8 Comments
Good root cause analysis. The OSC 8 sequences get clobbered by Ink's re-rendering.
Instead of using Claude Code's statusline, run your own status display in a tmux pane:
Then update it from a Notification hook:
This keeps the hyperlinks in a separate rendering context that Ink can't clobber.
Also ensure tmux passes OSC 8 through:
Additional reproduction data from #45173
Ran a systematic test with a minimal repro script to isolate the issue. Confirming the root cause analysis in this ticket.
Repro script
Configure in
~/.claude/settings.json:Test matrix
| Context | Clickable? |
|---------|-----------|
| Script run directly in terminal (no tmux) | Yes |
| Script run directly in tmux pane | Yes |
| Claude Code statusline (no tmux) | Yes |
| Claude Code statusline (inside tmux) | No |
| Claude Code statusline (tmux, fresh session) | No |
| Regular hyperlinks in Claude Code output (inside tmux) | Yes |
Variants tested (all inside tmux, all still broken)
| Variant | Result |
|---------|--------|
|
\e\\(ST) as OSC 8 terminator | Not clickable ||
\a(BEL) as OSC 8 terminator | Not clickable ||
CLAUDE_CODE_NO_FLICKER=1| Not clickable ||
CLAUDE_CODE_NO_FLICKERunset (default) | Not clickable ||
set -ga terminal-features ",xterm-256color:hyperlinks"in tmux.conf | Not clickable ||
set -g allow-passthrough onin tmux.conf | Not clickable |Key observation
tmux fully supports OSC 8 — hyperlinks work in regular pane content AND in Claude Code's own output (e.g. PR links rendered in conversation). The issue is exclusively in the statusline rendering path, consistent with the analysis that statusline content bypasses Ink's React component tree where OSC 8 round-tripping is preserved.
Environment
Closing for now — inactive for too long. Please open a new issue if this is still relevant.
This is a bug -- I would suggest leaving it open and fixing it
https://github.com/anthropics/claude-code/issues/26356#issuecomment-4554200330
I think somehow this is fixed now... I'm no longer having the issue
relates to https://github.com/anthropics/claude-code/issues/26356
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.