Cmd+click on file links in iTerm2 fails with "The application can't be opened. -50" — OSC 8 URI lacks file:// scheme

Status Fixed / completed
Reported on v2.1.205
Maintainer reply ✓ Yes — bcherny
Activity 4 comments · opened Jul 9, 2026 · closed Aug 20, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

Summary

Cmd+clicking a file link in Claude Code's output inside iTerm2 shows a macOS error dialog — "The application can't be opened. -50" — instead of opening the file. The OSC 8 hyperlink Claude Code emits for file paths uses the bare filesystem path as the URI, with no file:// scheme. iTerm2 (like other terminals that handle hyperlink clicks natively) passes the URI to NSWorkspace openURL:, and Launch Services rejects a scheme-less URL with paramErr (-50).

Environment

  • Claude Code 2.1.205 (Homebrew cask claude-code@latest)
  • macOS 26.5 (25F71)
  • iTerm2 3.6.10
  • tmux 3.6b (tmux is not the cause — see below)

Repro

  1. Run claude in iTerm2 (with or without tmux).
  2. Have Claude write a file so its output contains a clickable file path (e.g. Wrote .claude/brainstorm/foo.md).
  3. Cmd+click the path.
  4. macOS alert: "The application can't be opened. -50".

Evidence

Raw OSC 8 bytes captured from the pane (tmux capture-pane -e) show the emitted URI is a bare path:

\e]8;;/Users/eugenechan/dev/personal/lfg/.claude/brainstorm/multihost-first-rearchitecture.md\e\

(tmux is exonerated: injecting a file:///... OSC 8 link into the same pane survives round-trip with the scheme intact, and cmd+clicking it opens the file correctly.)

iTerm2 debug log of the click shows iTerm2 treating it as a URL action and dispatching the scheme-less URI:

iTermURLActionFactory.m:366 Found hypertext url /Users/…/multihost-first-rearchitecture.md
URLAction actionType=OpenURL string=/Users/…/multihost-first-rearchitecture.md
NSWorkspace+iTerm.m:211 it_openIfNonWebURL: Non-web scheme

Direct replication of the failure with a scheme-less URL:

NSWorkspace.shared.open(URL(string: "/Users/me/file.md")!, configuration: .init()) { _, err in print(err) }
// Error Domain=NSOSStatusErrorDomain Code=-50 "paramErr" (_LSOpenStuffCallLocal, LSOpenCore.mm)

Why iTerm2 never forwards the click to Claude Code

The 2.1.196 feature ("clickable file attachments in chat — Cmd/Ctrl-click reveals the file in Finder/Explorer") appears to expect Claude Code's own mouse handling to receive the cmd+click. iTerm2 deliberately does not report clicks on hyperlink ranges to the application (debug log: "In underlined range so don't report / Mouse reporting disallowed") — it opens the link itself. So on iTerm2 the emitted URI is what macOS receives, and it must be a valid URL.

Regression window

Worked before upgrading (pre-2.1.196 emitted file paths as plain text, so iTerm2's Semantic History opened them with the default app). Broken after upgrading to 2.1.205.

Suggested fix

Emit the hyperlink URI as a proper RFC 8089 file URL — pathToFileURL(path).href — as some other link emission in the codebase already does (there is an existing helper that does exactly ` \x1B]8;;${pathToFileURL(e).href}\x07… `). Terminals that open hyperlinks natively (iTerm2) then open the file with the user's default app, and Claude Code's internal cmd+click handling can continue to work on terminals that forward the click.

View original on GitHub ↗

3 Comments

Kondamon · 3 months ago

I filed #78481 for this before finding your report — closing mine as a duplicate. Your analysis is correct and better evidenced (I never managed to capture the raw bytes). Three things from my investigation that may be additive:

1. Still reproduces on 2.1.212 (you reported 2.1.205), macOS 26 / Darwin 25.5.0, iTerm2 3.6.11. Also confirmed independent of tmux, and independent of whether the path carries a :line suffix.

2. The offending emitter. You noted the codebase already has a correct helper. For precision, here are both sites from the 2.1.212 bundle (minified; names won't map to source):

// correct — always produces a scheme (this is the one #78109 is about):
function e7(e){ if(!y0()) return e;
  return `\x1B]8;;${UBd.pathToFileURL(e).href}\x07${e}\x1B]8;;\x07` }

// the bug — interpolates the raw string as the URI, no scheme conversion:
var O2d="\x1B]8;;", P2d="\x07";
let u = (((r?.themeName)?wQn(r.themeName):!1)?gt.blue:gt.blueBright)(t??e);
return `${O2d}${e}${P2d}${u}${O2d}${P2d}`;

The second site uses e verbatim as the hyperlink target, so a filesystem path yields a scheme-less URI. Both are gated by the same y0() hyperlink check, which is why FORCE_HYPERLINK=0 suppresses the symptom.

3. Prior art — Ghostty hit this exact bug and fixed it terminal-side. ghostty-org/ghostty#8599 ("Claude Code Link to local files fails to open file: The application can't be opened -50"), fixed in Ghostty 1.2.1 via PR #8764. Their captured log matches your -50 exactly:

LAUNCH: Launch failed in CSUI with error Error Domain=NSOSStatusErrorDomain
Code=-50 "paramErr: error in user parameter list"

…via _LSOpenStuffCallLocal. Their patch:

- guard let url = URL(string: action.url) else { ... }
+ // The URL initializer will gladly take invalid URLs (e.g. plain file paths) and turn
+ // them into schema-less URLs, but these won't open properly in text editors.
+ if let candidate = URL(string: action.url), candidate.scheme != nil { url = candidate }
+ else { url = URL(filePath: action.url) }

Worth noting mainly as evidence the emitted URI is malformed by any terminal's reckoning — Ghostty chose to defend against it, iTerm2 doesn't, but the fix belongs upstream either way.

Note on #78109: that one is a genuinely different defect (:line passed to pathToFileURL → a well-formed file:// URI pointing at a nonexistent path → NSCocoaErrorDomain 260, not -50). Same emitter family, different failure. Fixing this one won't fix that one.

wieTW · 2 months ago

Another data point from macOS + iTerm2 3.6.6 — in this variant the href isn't just missing the scheme, it's empty: right-clicking a rendered file path in iTerm2 and choosing Copy Link yields the literal string file:// with no path at all.

Cmd+click accordingly fails with the macOS "The application can't be opened." dialog. Unified log signature (differs from the -50 paramErr in the OP; captured on a zh-TW locale system — Code=258 is NSFileReadInvalidFileNameError):

CoreServicesUIAgent [com.apple.launchservices:error] ... came up with kLSUnknownError for Error Domain=NSCocoaErrorDomain Code=258 "檔案名稱無效。" UserInfo={NSURL=file://}
CoreServicesUIAgent [com.apple.launchservices:default] LAUNCH: Launch failed in CSUI with error Error Domain=NSOSStatusErrorDomain Code=-10810 "kLSUnknownErr"

22 such failures over ~50 minutes of normal use. The affected paths are plain ASCII, no spaces, and the files exist. Seen on both 2.1.225 and 2.1.226.

Two observations that may help narrow it down:

  • Print mode (claude -p) emits the same path as plain text — no OSC 8 at all.
  • Web URLs are emitted correctly (e.g. the startup screen's docs link comes out as \e]8;id=…;https://code.claude.com/…\a), so only the file-path emitter appears affected.

Quick check for anyone else landing here: right-click the path → Copy Link. A bare file:// (or a scheme-less path) confirms this bug. FORCE_HYPERLINK=0 works as a workaround, at the cost of losing all hyperlinks.

Environment: Claude Code 2.1.225/2.1.226 (native install), iTerm2 3.6.6, macOS Darwin 24.6.0.

bcherny collaborator · 1 month ago

Thanks for the excellent diagnosis — the raw OSC 8 capture and the NSWorkspace -50 replication made this easy to verify.

I checked the current release (2.1.233) by running Claude Code under tmux with hyperlinks enabled, having it write a file, and capturing the raw escape bytes from the pane. The file link is now emitted with a proper scheme:

ESC]8;id=…;file:///tmp/…/hello.txt ESC\

So the bare-path URI you captured on 2.1.205 has been fixed in a recent release — terminals like iTerm2 that open hyperlinks natively now receive a valid file:// URL, which Launch Services accepts. The link construction is shared across platforms, so this applies to macOS as well.

See the changelog for what's shipped since 2.1.205. Please update (claude update or your Homebrew cask) and cmd+click should open the file with your default app again.

Closing as fixed — reply here if you still see the bare-path URI on the latest version and we'll reopen.

🤖 Generated with Claude Code

Showing cached comments. Read the full discussion on GitHub ↗