[BUG] Codicon font blocked by webview CSP font-src — diff markers render as tofu on 2.1.116 (extends #26836)
Preflight Checklist
- [x] I have searched existing issues — this extends #26836 which was auto-closed for inactivity but remains unfixed on current release
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code (2.1.116)
What's Wrong?
In the Claude Code VS Code Extension chat panel, every diff line renders with an empty tofu square (☐) in the gutter instead of the proper codicon + / − glyphs. Root cause: the extension's webview bundles the codicon font as a data:font/ttf;base64,... source in @font-face, but the webview's Content Security Policy does not include data: in its font-src directive, so Chromium silently rejects the font.
This issue was originally reported in #26836 (auto-closed by the stale-bot despite multiple confirmations of it still reproducing). This report adds:
- A definitive root-cause trace using DevTools
FontFaceAPI - Verification that the embedded codicon TTF is valid (all 462 PUA glyphs present via cmap fmt 12)
- A verified, working workaround
- Two concrete proposed fixes for the extension
What Should Happen?
.codicon-diff-insert / .codicon-diff-remove elements in the diff view render as + and − glyphs from the embedded codicon font.
Error Messages/Logs
DevTools Issues tab shows 4 blocked directives on every diff render:
AFFECTED RESOURCES
4 directives
Resource Status Directive Source location
data blocked font-src index.html?id=4cedd4...:0
data blocked font-src index.html?id=96853a...:0
data blocked font-src index.html?id=b44a3b...:0
data blocked font-src index.html?id=fe4090...:0
document.fonts reports the codicon font in error state:
[...document.fonts].filter(f => f.family === 'codicon')
// => [{ status: "error", family: "codicon" }]
The CSS injection itself works — .codicon-diff-insert::before { content: '<PUA char>' } is correctly applied at runtime (verified via getComputedStyle(el, '::before').content), the character is valid (U+EA60 / U+EB3B), but the font to render it failed to load.
Steps to Reproduce
- Install Claude Code VS Code Extension v2.1.116 on Windows 11.
- Open any project in VS Code, start Claude Code, ask it to edit a file (any
Edit/Writetool call triggers the diff view in the chat panel). - Every diff line in the result renders with a tofu square instead of
+/−glyphs next to it. - In VS Code:
Ctrl+Shift+P→Developer: Open Webview Developer Tools→Issuestab — see 4font-src blocked data:violations. - Console:
``js``
[...document.fonts].filter(f => f.family === 'codicon').map(f => f.status)
// => ["error"]
Root Cause
File: C:\Users\<user>\.vscode\extensions\anthropic.claude-code-<ver>-win32-x64\webview\index.css
@font-face {
font-family: codicon;
font-display: block;
src: url(data:font/ttf;base64,AAEAAAALAIAAAwAw...); /* ← blocked by CSP font-src */
font-weight: normal;
font-style: normal;
}
The embedded TTF is valid (decoded and parsed: sfnt 0x00010000, 462 glyphs, cmap format 12 covers U+EA60 .. U+F101 with all expected codicon codepoints present). The problem is purely CSP — the webview's CSP meta tag defines font-src as an allowlist that excludes data:.
Proposed Fixes (either works)
Option A — Relax the webview CSP. Add data: to the font-src directive of the <meta http-equiv="Content-Security-Policy"> set when constructing the webview HTML. Minimal change, single-line diff.
Option B — Host the font as a webview-local resource. Ship codicon.ttf as an actual file under webview/ (or resources/) and reference it via vscode-resource: / asWebviewUri(), then add the corresponding path to font-src. This is the cleaner long-term solution and matches how VS Code Core serves codicons to its built-in webviews.
Working Workaround (verified)
Patch webview/index.css to prepend local() sources so Chromium uses a system-installed codicon font instead of the blocked data: URI:
@font-face {
font-family: codicon;
font-display: block;
src: local('codicon'), url(data:font/ttf;base64,AAEA...); /* ← added local() first */
...
}
Plus install the codicon font system-wide (decoded from the extension's own embedded @font-face → %LOCALAPPDATA%\Microsoft\Windows\Fonts\codicon.ttf, registered in HKCU\Software\Microsoft\Windows NT\CurrentVersion\Fonts, loaded via Win32 AddFontResourceW + WM_FONTCHANGE broadcast).
After VS Code window reload, codicon glyphs render correctly in diff views. local() is not CSP-gated (it doesn't make a network request), so it bypasses the font-src restriction. But this patch is invasive and gets overwritten on every extension update — it's a workaround, not a fix.
Claude Model
N/A (UI rendering bug, not model behavior)
Is this a regression?
Yes — originally reported on 2.1.39 in #26836, still reproduces on 2.1.116.
Last Working Version
Per #26836: last confirmed working in VS Code 1.109.4. Claude Code extension version when it worked: unknown.
Claude Code Version
2.1.116
Platform
Claude.ai (Max subscription)
Operating System
Windows 11 Pro 10.0.26200
Terminal/Shell
VS Code integrated terminal (PowerShell 7)
Additional Information
- Confirming users on the parent issue (#26836): @MtkN1 on 2.1.109, @jrynlds-pinc on 2.1.116 (2026-04-20).
- Disabling the bundled CSP or switching to a strict CSP (both recommended by Chromium's Issues panel) would also resolve this, but Option A/B above are the minimal targeted fixes.
- Unrelated but adjacent observation while inspecting the same webview:
Uncaught TypeError: Cannot read properties of undefined (reading 'toUrl')thrown fromkv.toUri → kv.asBrowserUri → nP.$loadForeignModuleinwebview/index.js. Surfaces regularly during diff view init. Filing as a separate issue if it doesn't go away after the font fix.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗