OAuth authorization URL not wrapped in OSC 8 hyperlink, causing truncation in terminal emulators

Resolved 💬 3 comments Opened Feb 6, 2026 by yuri-g-taboola Closed Mar 7, 2026

Describe the bug

When authenticating Claude Code, the OAuth authorization URL displayed in the terminal is not wrapped in OSC 8 hyperlink escape sequences. This causes terminal emulators that rely on regex-based link detection (like xterm.js/ttyd) to truncate the URL when it wraps across multiple lines, resulting in "Invalid OAuth Request - Missing state parameter" errors when clicking the link.

To reproduce

  1. Run Claude Code in a terminal that uses xterm.js (e.g., ttyd, VS Code terminal, web-based terminals)
  2. Trigger OAuth authentication (e.g., first-time login)
  3. Observe the authorization URL displayed after "Authenticate your account at (press ENTER to open in browser):"
  4. Click the URL - it opens with missing query parameters (truncated at line wrap)

Expected behavior

The OAuth URL should be wrapped with OSC 8 hyperlink escape sequences, similar to how the existing link(url) function works:

function link(url) {
  if (enableANSIColors)
    return `\x1B[1m\x1B]8;;${url}\x1B\\${url}\x1B]8;;\x1B\\\x1B[22m`;
  return url;
}

This would make the entire URL (including wrapped portions) clickable as a single hyperlink, bypassing regex-based terminal link detection.

Workaround

Manually copy-paste the URL instead of clicking it.

Environment

  • Claude Code version: latest (installed via curl -fsSL https://claude.ai/install.sh | bash)
  • Terminal: ttyd with xterm.js (also affects VS Code integrated terminal and other xterm.js-based terminals)
  • OS: Linux (Rocky Linux 9 in Docker container)

Additional context

  • Claude Code already has OSC 8 support via the link(url) function, but it is not being used for the OAuth authorization URL
  • This is similar to the resolved issue #3498 (Windows terminal URL truncation), but affects xterm.js-based terminals
  • Related feature request: #13008 (OSC 8 hyperlinks for file paths)

The fix would be to wrap the OAuth URL with the existing link() function when displaying it to the user.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗