[BUG] iTerm2: Cmd-click on file paths fails with LaunchServices -50 (OSC 8 URI includes :line)

Status Closed — duplicate
Reported on v2.1.211
Maintainer reply None cached
Activity 1 comment · opened Jul 16, 2026 · closed Aug 19, 2026

Summary

Claude Code wraps file references (path:line) in OSC 8 hyperlinks whose URI is built by calling pathToFileURL() on the full path:line string. This produces a file:// URI pointing at a file that cannot exist. In iTerm2, Cmd-clicking such a path shows a macOS error:

The application can't be opened. -50

-50 is paramErr from LaunchServices — it cannot resolve the URI.

Environment

  • Claude Code 2.1.211
  • macOS (Darwin 25.5.0)
  • iTerm2 3.6.11
  • Reproduces both inside and outside tmux 3.6a

Reproduction

  1. Run Claude Code in iTerm2
  2. Get it to print a file reference, e.g. /path/to/docs/EXAMPLE.md:238 (any real file + line)
  3. Cmd-click the path
  4. macOS shows The application can't be opened. -50

Cause

function Pz(e){ if(!aR()) return e;
  return `\x1B]8;;${pathToFileURL(e).href}\x07${e}\x1B]8;;\x07` }

The same e is used for both the URI and the visible label. When e is /path/to/docs/EXAMPLE.md:238, pathToFileURL() percent-escapes the colon into the filename, yielding:

file:///path/to/docs/EXAMPLE.md:238

No such file exists (:238 is not part of any filename), so LaunchServices returns paramErr (-50).

Because the label and the URI derive from the same e, the rendered label is direct evidence of what the URI contains — if you can see EXAMPLE.md:238 as the link text, the URI has :238 in the path component.

Why this specifically breaks iTerm2

  • iTerm2 is listed in Claude Code's own terminal map: {ghostty, kitty, "iTerm.app", WezTerm, Warp, "windows-terminal"}
  • kitty and ghostty let users configure open_actions to pattern-match a file://...:line URI and route it to an editor. iTerm2 has no equivalent hook.
  • iTerm2 does have Semantic History, which parses path:line from plain text correctly and opens the configured editor at the right line.
  • An explicit OSC 8 hyperlink takes precedence over Semantic History. So the link doesn't just fail — it actively suppresses the mechanism that would have worked.

Net effect on iTerm2: emitting the hyperlink makes Cmd-click strictly worse than emitting plain text.

Note that even a corrected URI (file:///path/to/docs/EXAMPLE.md) would not solve this: a plain file:// URI has no standard way to carry a line number, so the click would land on line 1. Line numbers in file URIs are conventions only (:238, #L238, ?line=238), none of which pathToFileURL() produces.

Workaround

export FORCE_HYPERLINK=0

This disables Pz() via the aR() gate, so paths render as plain text and Semantic History handles them.

Scope of the workaround, for reference:

  • Pz() (file paths) — gated by aR() → disabled
  • the generic link helper (RFd/xFd) — gated → degrades to label (url), still readable
  • VOd() (remote-control / attached-item links) — not gated → keeps working

Suggested fix

Any of:

  1. Don't emit OSC 8 for file paths on terminals that lack a line-aware open hook (iTerm2 in particular, where Semantic History already handles it better).
  2. Strip :line from the URI before calling pathToFileURL(), so the link at least resolves.
  3. Use an editor scheme that carries the line — the same binary already has this shape for VS Code: vscode://file/{path}:{line}:{column}.

Option 1 seems most correct for iTerm2: the terminal's native mechanism is strictly better than any file:// URI can be.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗