[BUG] VS Code extension: some file links on Windows do nothing when clicked
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?
Three defects on the "click a file path in the transcript to open it" path. All reproduce on any Windows install. Located by reading the shipped bundles (no sourcemaps), so I'm quoting the minified expressions rather than line numbers.
1. File-link labels show the full absolute path instead of the basename
webview/index.js, ReadCoalesced.header and 10 sibling sites:
let G = Y.file_path.split("/").pop() || Y.file_path;
POSIX-only basename. A Windows path contains no /, so pop() returns the whole string and the fallback never fires. The transcript renders:
<span class="toolNameText">Read </span>
<span class="toolNameTextSecondary"><a href="#">D:\foo\bar\baz\shots\final.png</a></span>
Expected final.png.
Fix: .split(/[\/]/).pop()
Same expression appears in the headers/permission prompts for Read, ReadCoalesced, Edit, Write, NotebookEdit and the plan-file link — 11 occurrences in the bundle, all basenames, all safe to convert.
---
2. openFile swallows the rejection for binary files, so image links do nothing
extension.js:
E$.window.showTextDocument(X).then((Y) => { /* reveal range */ })
No .catch. showTextDocument rejects on a binary file ("File seems to be binary and cannot be opened as text"), so clicking a link to a .png produces an unhandled rejection and zero user-visible feedback. The path resolution above it is correct; only the presentation call is wrong.
Fix: fall back to the default editor resolution:
E$.window.showTextDocument(X).then((Y) => { ... })
.catch(() => E$.commands.executeCommand("vscode.open", X))
vscode.open routes images to the image editor and text to the text editor, so it is a safe fallback for the whole class, not just images.
---
3. Markdown links to absolute Windows paths are inert
When Claude writes a markdown link to an absolute path, two layers drop it.
3a. The markdown a component passes href straight through react-markdown's default URL sanitizer. C:/Users/... parses as scheme c:, which is not in the allowlist, so the rendered anchor is:
<a href="" target="_blank" rel="noopener noreferrer">claude-vscode-linkfix.sh</a>
3b. Even with the href intact, the path parser rejects it:
function Cx($) {
...
let J = /^([^:#]+?)(?:[:#]L?(\d+)(?:-L?(\d+))?)?$/;
[^:#]+? forbids colons in the path segment — the colon is reserved for the :42 line suffix — so C:/… and D:\… can never match. Cx returns null, the click handler returns before reaching fileOpener.open, and the anchor does nothing.
Fix (3b): allow a leading drive letter —/^((?:[A-Za-z]:)?[^:#]+?)(?:[:#]L?(\d+)(?:-L?(\d+))?)?$/
The rest of Cx's allowlist already accepts a drive path via its file-extension test.
Fix (3a) needs a urlTransform that lets drive-letter paths through while keeping the sanitizer for everything else — a blanket passthrough would re-admit javascript: hrefs in rendered model and tool output, so this one wants care on your side rather than a one-liner.
What Should Happen?
Links are basic stuff, but let me check.
Based on wikipedia, in computing, a hyperlink, or simply a link, is a digital reference providing direct access to data) by a user's) clicking or tapping.[[1]](https://en.wikipedia.org/wiki/Hyperlink#cite_note-1)
It should do that.
Error Messages/Logs
Steps to Reproduce
On Windows, in the vscode extension chat:
- Have Claude read any file → the link label is the full absolute path (1).
- Have Claude read a
.png→ click the link → nothing happens, no error (2). - Have Claude write a markdown link to an absolute path such as
C:/Users/you/notes.md→ the anchor renders with an emptyhrefand is not clickable (3).
#1 and #2 verified fixed locally by patching the shipped bundles with the two changes above.
Claude Model
None
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.246 (Claude Code)
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Other
Additional Information
Here is a patch that will fix 1+2, but that would need to be reapplied on every update.
#!/usr/bin/env bash
# Fix Windows file links in the Claude Code VS Code extension.
# 1. basename via split("/") -> whole path shown as the link label on Windows
# 2. openFile only calls showTextDocument -> rejects silently on binary files (png etc)
# Re-run after every extension update, then reload the VS Code window.
set -euo pipefail
EXT_DIR="${1:-}"
if [ -z "$EXT_DIR" ]; then
EXT_DIR=$(ls -d "$HOME"/.vscode/extensions/anthropic.claude-code-*-win32-x64 | sort -V | tail -1)
fi
echo "target: $EXT_DIR"
W="$EXT_DIR/webview/index.js"
X="$EXT_DIR/extension.js"
for f in "$W" "$X"; do [ -f "$f.orig" ] || cp "$f" "$f.orig"; done
SEP='[\\/]'
sub() { OLD="$1" NEW="$2" perl -pi -e 'BEGIN{$o=$ENV{OLD};$n=$ENV{NEW}} s/\Q$o\E/$n/g' "$3"; }
sub '.split("/").pop()' ".split(/$SEP/).pop()" "$W"
sub 'z.end)}})}openConfigFile' 'z.end)}}).catch(()=>E$.commands.executeCommand("vscode.open",X))}openConfigFile' "$X"
echo "basename sites patched: $(grep -oF "split(/$SEP/).pop()" "$W" | wc -l)"
echo "openFile fallback: $(grep -cF 'vscode.open",X' "$X")"
node --check "$X" && echo "extension.js parses"