[BUG] PDF

Status Open
Reported on v2.1.251
Maintainer reply None cached
Activity 1 comment · opened Aug 29, 2026

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

  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 → preventDefaultpostMessage {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.

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

  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 → preventDefaultpostMessage {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.

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

  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 → preventDefaultpostMessage {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.

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

  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 → preventDefaultpostMessage {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.

View original on GitHub ↗

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