[BUG] PDF
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?
[BUG] VSCode extension: clicking a PDF (or any binary) file link in chat does nothing — silent showTextDocument rejection
Version: Claude Code VSCode extension 2.1.251 (win32-x64) · VSCode on Windows 11 Pro 10.0.26200
Related: #37989 (same root cause, PNG focus, closed as not planned/stale). This report adds the exact code paths, verified against the shipped bundle.
Repro
- Have any real PDF in the workspace (e.g.
apuestas/reportes/MLB-Kalshi-2026-08-29.pdf, 130 KB). - Have Claude reply with a relative markdown link to it:
[report](apuestas/reportes/MLB-Kalshi-2026-08-29.pdf). - Click the link in the chat transcript panel.
Expected: the PDF opens — via the registered custom editor if one exists (e.g. tomoki1207.pdf registers pdf.preview for *.pdf), else via an error message telling the user why not.
Actual: nothing visible happens. No editor, no toast, no output-channel entry.
Root cause (read from the shipped minified bundles)
- Webview (
webview/index.js, byte ~317043): anchor clicks runWV0, which calls the path detectorvx(~314038). A colon-free, path-looking href (has an extension, or starts with/ ./ ../) matches →preventDefault→postMessage {type:'request', request:{type:'open_file', filePath, location}}. So the click IS delivered for relative PDF links. - Extension host (
extension.js, byte ~2951571): theopen_filehandler resolves the path against the session cwd (file exists), then callsvscode.window.showTextDocument(Uri.file(path))unconditionally — a text-only API that never consults registered custom editors. A binary PDF makes the promise reject ("file is binary"); the code attaches only a.thenfulfillment handler and no.catch, so the rejection is silently swallowed. Hence "click does nothing". - There is no per-extension special-casing anywhere in the bundle (no
vscode.open, noopenWithon this path — verified by exhaustive grep).
Also dead, for a different reason: file:///... and C:\... hrefs never match vx (the colon breaks the regex ^([^:#]+?)(?:[:#]L?\d+(?:-L?\d+)?)?$), fall through to VSCode's webview link interception, whose scheme allowlist (http/https/mailto) drops them silently. So there is no markdown link form that can open a local binary file from the chat panel.
Suggested fix
In the open_file host handler, when the target isn't a directory:
- try
showTextDocumentas today, but add a.catchthat falls back tovscode.commands.executeCommand('vscode.open', uri)— this routes binaries to VSCode's built-in previews and to registered custom editors (pdf.preview, image preview, notebook editors); - or detect known binary extensions up front and use
vscode.opendirectly; - at minimum, surface the rejection (toast) instead of swallowing it.
One-line impact: any report/artifact PDF, image, or notebook Claude produces is un-openable from its own chat link, and the failure is invisible to the user.
What Should Happen?
[BUG] VSCode extension: clicking a PDF (or any binary) file link in chat does nothing — silent showTextDocument rejection
Version: Claude Code VSCode extension 2.1.251 (win32-x64) · VSCode on Windows 11 Pro 10.0.26200
Related: #37989 (same root cause, PNG focus, closed as not planned/stale). This report adds the exact code paths, verified against the shipped bundle.
Repro
- Have any real PDF in the workspace (e.g.
apuestas/reportes/MLB-Kalshi-2026-08-29.pdf, 130 KB). - Have Claude reply with a relative markdown link to it:
[report](apuestas/reportes/MLB-Kalshi-2026-08-29.pdf). - Click the link in the chat transcript panel.
Expected: the PDF opens — via the registered custom editor if one exists (e.g. tomoki1207.pdf registers pdf.preview for *.pdf), else via an error message telling the user why not.
Actual: nothing visible happens. No editor, no toast, no output-channel entry.
Root cause (read from the shipped minified bundles)
- Webview (
webview/index.js, byte ~317043): anchor clicks runWV0, which calls the path detectorvx(~314038). A colon-free, path-looking href (has an extension, or starts with/ ./ ../) matches →preventDefault→postMessage {type:'request', request:{type:'open_file', filePath, location}}. So the click IS delivered for relative PDF links. - Extension host (
extension.js, byte ~2951571): theopen_filehandler resolves the path against the session cwd (file exists), then callsvscode.window.showTextDocument(Uri.file(path))unconditionally — a text-only API that never consults registered custom editors. A binary PDF makes the promise reject ("file is binary"); the code attaches only a.thenfulfillment handler and no.catch, so the rejection is silently swallowed. Hence "click does nothing". - There is no per-extension special-casing anywhere in the bundle (no
vscode.open, noopenWithon this path — verified by exhaustive grep).
Also dead, for a different reason: file:///... and C:\... hrefs never match vx (the colon breaks the regex ^([^:#]+?)(?:[:#]L?\d+(?:-L?\d+)?)?$), fall through to VSCode's webview link interception, whose scheme allowlist (http/https/mailto) drops them silently. So there is no markdown link form that can open a local binary file from the chat panel.
Suggested fix
In the open_file host handler, when the target isn't a directory:
- try
showTextDocumentas today, but add a.catchthat falls back tovscode.commands.executeCommand('vscode.open', uri)— this routes binaries to VSCode's built-in previews and to registered custom editors (pdf.preview, image preview, notebook editors); - or detect known binary extensions up front and use
vscode.opendirectly; - at minimum, surface the rejection (toast) instead of swallowing it.
One-line impact: any report/artifact PDF, image, or notebook Claude produces is un-openable from its own chat link, and the failure is invisible to the user.
Error Messages/Logs
# [BUG] VSCode extension: clicking a PDF (or any binary) file link in chat does nothing — silent showTextDocument rejection
**Version:** Claude Code VSCode extension 2.1.251 (win32-x64) · VSCode on Windows 11 Pro 10.0.26200
**Related:** #37989 (same root cause, PNG focus, closed as not planned/stale). This report adds the exact code paths, verified against the shipped bundle.
## Repro
1. Have any real PDF in the workspace (e.g. `apuestas/reportes/MLB-Kalshi-2026-08-29.pdf`, 130 KB).
2. Have Claude reply with a relative markdown link to it: `[report](apuestas/reportes/MLB-Kalshi-2026-08-29.pdf)`.
3. Click the link in the chat transcript panel.
**Expected:** the PDF opens — via the registered custom editor if one exists (e.g. `tomoki1207.pdf` registers `pdf.preview` for `*.pdf`), else via an error message telling the user why not.
**Actual:** nothing visible happens. No editor, no toast, no output-channel entry.
## Root cause (read from the shipped minified bundles)
1. **Webview** (`webview/index.js`, byte ~317043): anchor clicks run `WV0`, which calls the path detector `vx` (~314038). A colon-free, path-looking href (has an extension, or starts with `/ ./ ../`) matches → `preventDefault` → `postMessage {type:'request', request:{type:'open_file', filePath, location}}`. So the click IS delivered for relative PDF links.
2. **Extension host** (`extension.js`, byte ~2951571): the `open_file` handler resolves the path against the session cwd (file exists), then calls **`vscode.window.showTextDocument(Uri.file(path))` unconditionally** — a text-only API that never consults registered custom editors. A binary PDF makes the promise reject ("file is binary"); the code attaches only a `.then` fulfillment handler and **no `.catch`**, so the rejection is silently swallowed. Hence "click does nothing".
3. There is no per-extension special-casing anywhere in the bundle (no `vscode.open`, no `openWith` on this path — verified by exhaustive grep).
Also dead, for a different reason: `file:///...` and `C:\...` hrefs never match `vx` (the colon breaks the regex `^([^:#]+?)(?:[:#]L?\d+(?:-L?\d+)?)?$`), fall through to VSCode's webview link interception, whose scheme allowlist (http/https/mailto) drops them silently. So there is **no** markdown link form that can open a local binary file from the chat panel.
## Suggested fix
In the `open_file` host handler, when the target isn't a directory:
- try `showTextDocument` as today, **but add a `.catch`** that falls back to `vscode.commands.executeCommand('vscode.open', uri)` — this routes binaries to VSCode's built-in previews and to registered custom editors (pdf.preview, image preview, notebook editors);
- or detect known binary extensions up front and use `vscode.open` directly;
- at minimum, surface the rejection (toast) instead of swallowing it.
One-line impact: any report/artifact PDF, image, or notebook Claude produces is un-openable from its own chat link, and the failure is invisible to the user.
Steps to Reproduce
[BUG] VSCode extension: clicking a PDF (or any binary) file link in chat does nothing — silent showTextDocument rejection
Version: Claude Code VSCode extension 2.1.251 (win32-x64) · VSCode on Windows 11 Pro 10.0.26200
Related: #37989 (same root cause, PNG focus, closed as not planned/stale). This report adds the exact code paths, verified against the shipped bundle.
Repro
- Have any real PDF in the workspace (e.g.
apuestas/reportes/MLB-Kalshi-2026-08-29.pdf, 130 KB). - Have Claude reply with a relative markdown link to it:
[report](apuestas/reportes/MLB-Kalshi-2026-08-29.pdf). - Click the link in the chat transcript panel.
Expected: the PDF opens — via the registered custom editor if one exists (e.g. tomoki1207.pdf registers pdf.preview for *.pdf), else via an error message telling the user why not.
Actual: nothing visible happens. No editor, no toast, no output-channel entry.
Root cause (read from the shipped minified bundles)
- Webview (
webview/index.js, byte ~317043): anchor clicks runWV0, which calls the path detectorvx(~314038). A colon-free, path-looking href (has an extension, or starts with/ ./ ../) matches →preventDefault→postMessage {type:'request', request:{type:'open_file', filePath, location}}. So the click IS delivered for relative PDF links. - Extension host (
extension.js, byte ~2951571): theopen_filehandler resolves the path against the session cwd (file exists), then callsvscode.window.showTextDocument(Uri.file(path))unconditionally — a text-only API that never consults registered custom editors. A binary PDF makes the promise reject ("file is binary"); the code attaches only a.thenfulfillment handler and no.catch, so the rejection is silently swallowed. Hence "click does nothing". - There is no per-extension special-casing anywhere in the bundle (no
vscode.open, noopenWithon this path — verified by exhaustive grep).
Also dead, for a different reason: file:///... and C:\... hrefs never match vx (the colon breaks the regex ^([^:#]+?)(?:[:#]L?\d+(?:-L?\d+)?)?$), fall through to VSCode's webview link interception, whose scheme allowlist (http/https/mailto) drops them silently. So there is no markdown link form that can open a local binary file from the chat panel.
Suggested fix
In the open_file host handler, when the target isn't a directory:
- try
showTextDocumentas today, but add a.catchthat falls back tovscode.commands.executeCommand('vscode.open', uri)— this routes binaries to VSCode's built-in previews and to registered custom editors (pdf.preview, image preview, notebook editors); - or detect known binary extensions up front and use
vscode.opendirectly; - at minimum, surface the rejection (toast) instead of swallowing it.
One-line impact: any report/artifact PDF, image, or notebook Claude produces is un-openable from its own chat link, and the failure is invisible to the user.
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
1.0.123
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
[BUG] VSCode extension: clicking a PDF (or any binary) file link in chat does nothing — silent showTextDocument rejection
Version: Claude Code VSCode extension 2.1.251 (win32-x64) · VSCode on Windows 11 Pro 10.0.26200
Related: #37989 (same root cause, PNG focus, closed as not planned/stale). This report adds the exact code paths, verified against the shipped bundle.
Repro
- Have any real PDF in the workspace (e.g.
apuestas/reportes/MLB-Kalshi-2026-08-29.pdf, 130 KB). - Have Claude reply with a relative markdown link to it:
[report](apuestas/reportes/MLB-Kalshi-2026-08-29.pdf). - Click the link in the chat transcript panel.
Expected: the PDF opens — via the registered custom editor if one exists (e.g. tomoki1207.pdf registers pdf.preview for *.pdf), else via an error message telling the user why not.
Actual: nothing visible happens. No editor, no toast, no output-channel entry.
Root cause (read from the shipped minified bundles)
- Webview (
webview/index.js, byte ~317043): anchor clicks runWV0, which calls the path detectorvx(~314038). A colon-free, path-looking href (has an extension, or starts with/ ./ ../) matches →preventDefault→postMessage {type:'request', request:{type:'open_file', filePath, location}}. So the click IS delivered for relative PDF links. - Extension host (
extension.js, byte ~2951571): theopen_filehandler resolves the path against the session cwd (file exists), then callsvscode.window.showTextDocument(Uri.file(path))unconditionally — a text-only API that never consults registered custom editors. A binary PDF makes the promise reject ("file is binary"); the code attaches only a.thenfulfillment handler and no.catch, so the rejection is silently swallowed. Hence "click does nothing". - There is no per-extension special-casing anywhere in the bundle (no
vscode.open, noopenWithon this path — verified by exhaustive grep).
Also dead, for a different reason: file:///... and C:\... hrefs never match vx (the colon breaks the regex ^([^:#]+?)(?:[:#]L?\d+(?:-L?\d+)?)?$), fall through to VSCode's webview link interception, whose scheme allowlist (http/https/mailto) drops them silently. So there is no markdown link form that can open a local binary file from the chat panel.
Suggested fix
In the open_file host handler, when the target isn't a directory:
- try
showTextDocumentas today, but add a.catchthat falls back tovscode.commands.executeCommand('vscode.open', uri)— this routes binaries to VSCode's built-in previews and to registered custom editors (pdf.preview, image preview, notebook editors); - or detect known binary extensions up front and use
vscode.opendirectly; - at minimum, surface the rejection (toast) instead of swallowing it.
One-line impact: any report/artifact PDF, image, or notebook Claude produces is un-openable from its own chat link, and the failure is invisible to the user.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗