[BUG] VS Code extension: chat file links with spaces / non-ASCII paths never open — host never percent-decodes (fix location + workaround inside)

Status Open
Reported on v2.1.280
Maintainer reply None cached
Activity 3 comments · opened Sep 24, 2026

Preflight Checklist

  • [x] I have searched existing issues. Prior reports #10846, #44713, #49218, #50452, #68718 and #76328 describe this bug; every one was auto-closed as duplicate or stale without a fix, and the closing bot asked to open a new issue if still relevant. It is still present in 2.1.280. This report adds two things the earlier ones lack: the exact fix location and a working user-side workaround.
  • [x] This is a single bug report
  • [x] I am using the latest version (extension 2.1.280, installed 2026-09-23)

What's Wrong?

In the VS Code extension chat, a markdown file link whose workspace-relative path contains a space or any non-ASCII character never opens on click. No error is shown. Links to pure-ASCII, space-free paths open fine.

The extension's own instructions tell the model to emit exactly these [name.md](path/name.md) links, so in any workspace with spaces or non-English folder/file names most chat links are dead.

Root cause (read from the 2.1.280 bundles)

  1. webview/index.js – chat markdown is rendered by react-markdown. A destination with a raw space is not a link at all (CommonMark). <...> and %20 forms do parse, but mdast-util-to-hast's normalizeUri percent-encodes every space and non-ASCII char, so the a component receives e.g. href="docs/My%20Folder/%C3%9Cbersicht.md".
  2. The custom a onClick parses path[#Lx[-Ly]] out of the href and sends { type: "open_file", filePath } to the host without decoding.
  3. extension.js – the host's openFile(filePath, location) does path.isAbsolute(p) ? p : <resolve in workspace roots> ?? path.join(cwd, p), and if that does not exist falls back to a fuzzy workspace.findFiles search using the same undecoded string. Nothing ever calls decodeURIComponent, so My%20Folder is looked up literally and fails silently.

Also verified dead ends, so there is no alternative link form: file:// links (VS Code webviews only forward http/https/mailto/vscode schemes to the opener service), command: URIs (enableCommandUris is not set), and absolute paths with spaces (no fuzzy fallback for absolute paths).

Steps to reproduce

  1. Open a workspace containing docs/My Folder/Übersicht.md (space in the folder, non-ASCII in the file name).
  2. Ask Claude to link to it. It emits [Übersicht.md](docs/My Folder/Übersicht.md) (renders as plain text) or, if told to encode, [Übersicht.md](docs/My%20Folder/%C3%9Cbersicht.md) (renders as a link).
  3. Click the link → nothing happens.
  4. Rename to docs/MyFolder/Uebersicht.md and link again → opens.

Expected Behavior

The path is percent-decoded before resolving, so docs/My%20Folder/%C3%9Cbersicht.md opens docs/My Folder/Übersicht.md, with #L12 / #L12-L20 anchors still honoured.

Suggested fix

One line in the host's openFile, before any lookup and before the findFiles fallback:

try { filePath = decodeURIComponent(filePath) } catch {}

Decoding on the host side also covers any other producer of encoded paths. (Decoding in the webview click handler before sending open_file works too.)

Workaround for users (verified on 2.1.280 / VS Code 1.135.0 / macOS)

The host's fuzzy fallback hands the string straight to workspace.findFiles as a glob whenever it contains * ? { } [ ], and the renderer leaves those characters untouched. So, in the link target only:

  • replace every space or comma with ? (one per character). Commas because VS Code's query builder splits include patterns on ,.
  • replace every non-ASCII character with *. ? cannot work there: ripgrep's -g filter counts bytes while VS Code's second JS glob filter counts UTF-16 units, and only * satisfies both.

[Übersicht.md](docs/My?Folder/*bersicht.md) and [notes.md](docs/My?Folder/notes.md#L12) open correctly. Limits: workspace-relative files only (no ../ siblings, no folders). It rides on an undocumented fallback, so it can break at any release. Not a substitute for the fix.

Environment

  • Extension: anthropic.claude-code 2.1.280 (darwin-arm64); also reproduced on 2.1.267–2.1.278
  • VS Code 1.135.0, macOS (Darwin 25.2). Earlier reports confirm Windows 10/11 as well.

View original on GitHub ↗

3 Comments

tobiasheckmann · 20 days ago

Note for triage: the issues the duplicate bot will link (#10846, #44713, #49218, #50452, #68718, #76328) are all closed as duplicate/stale, none fixed, and their closing messages ask for a new issue. Please don't auto-close this one; it carries the fix location and a verified workaround that the earlier reports lack.

Shifu-Ming · 20 days ago

+1, hitting this too. My workspace path uses non-ASCII (Traditional Chinese) folder names, which matches the root-cause analysis in this issue (spaces/non-ASCII in the href getting percent-encoded, then never decoded before the host-side file lookup — silent failure, no error).

Environment: macOS 15.6.1 (Sequoia), Claude Code VS Code native extension, CLI 2.1.270. Confirmed it was working before (relative-path markdown links were clickable), and has been broken since around v2.1.178 per #69240.

6DiegoDiego9 · 17 days ago

Still present in 2.1.282 (linux-x64 extension host in a Dev Container on WSL2, VS Code on Windows 11), same trace as described above:

  • webview/index.js: the link onClick parses the href that normalizeUri has already percent-encoded (My%20Folder/…, %C3%A0 for à) and sends it to open_file as filePath without decoding it.
  • extension.js: openFile() resolves that literal string, and the findFiles fallback uses it too, so the lookup fails silently.

Accented Latin letters in Italian folder and file names fail in exactly the same way as spaces. A decodeURIComponent (in a try) on the href before parsing path[:#Lx-Ly], or a retry with the decoded path in openFile() when the literal one does not exist, would fix both.

For a sense of the impact: to keep chat links usable I ended up renaming about 6,400 files and folders in a monorepo.