Repository navigation
[BUG] Claude Desktop silently hangs installing any local .mcpb with a deflated entry larger than ~16 KB #67865
Description
Activity
- addedplatform:windowsIssue specifically occurs on WindowsIssue specifically occurs on Windows
on Jun 12, 2026 This maps to a common enterprise rollout friction pattern: auth/proxy/policy boundaries blocking agent tool chains. A diagnostic approach:
- Trace the full call chain — which hop fails? Is it the auth handshake, the proxy tunnel, or the downstream tool call through the proxy?
- Env-var audit — proxy env vars (
HTTP_PROXY,HTTPS_PROXY,NO_PROXY) often get partially propagated across subprocess/spawn boundaries - Cert chain — if corporate CA certs are involved, verify they're in the trust store that the spawned process sees (not just the parent)
- Policy bypass test — isolate whether the block is at the network level (try direct connection) or auth level (try with a personal token)
We've been building hardening playbooks specifically for locked-down enterprise deployments of AI coding agents — happy to share the diagnostic checklist if useful.
Confirming on macOS (26.5, arm64) — same Desktop version, same silent hang, so this is not Windows-specific.
Claude Desktop 1.12603.1, bundles built by
mcpb packin CI (mcdev-mcp releases; 5.0 MB packed, 30 deflate entries over 16 KB compressed):- Opening the
.mcpb(double-click,open, or Settings → Extensions) logs onlyand then nothing — no preview dialog, no error, no CPU. Reproduced across multiple attempts and two different bundle versions (2.1.1, 2.2.0).2026-06-12 19:28:03 [info] Handling DXT/MCPB file: ~/Downloads/mcdev-mcp-2.2.0.mcpb - Can also confirm the misleading secondary symptom:
claude.ai-web.logaccumulatesError invoking remote method '…showInstallDxtDialog': reply was never senton later window reloads, not at the moment of the failed install. - Timeline matches the regression window: an earlier bundle of the same extension (equally mcpb-packed, same >16 KB deflate entries) installed fine on this machine earlier the same day, before the app updated to 1.12603.1.
- Workaround verified on macOS as well: repacking the identical extracted content with stored entries (
unzip … && zip -rX -Z store …) makes the preview dialog appear immediately, and install + server launch succeed:2026-06-12 23:18:46 [warn] Installing unsigned extension from ~/Downloads/mcdev-mcp-2.2.0-stored.mcpb 2026-06-12 23:18:49 [info] Successfully installed extension local.mcpb.weikengchen.mcdev-mcp v2.2.0
- Opening the
We hit this distributing our own .mcpb extension: silent install failures for a subset of users that turned out to track the staggered 1.12603.1 rollout. Some context that may save others time, plus the upstream chain.
The ~16 KB threshold measured here and the ~64 KB measured elsewhere are the same bug. The hang needs one backpressure pause near end-of-entry, which needs a compressed entry at least as large as Node's default stream highWaterMark: 16 KiB on Windows, 64 KiB on macOS/Linux (
lib/internal/streams/state.js). On macOS the boundary is byte-exact: a 65,535-byte compressed entry extracts, a 65,536-byte one hangs.Upstream: the regression is nodejs/node#62557 ("noop pause/resume on destroyed streams"), first shipped in Node 24.16.0 and 26.1.0, tracked in nodejs/node#63487. fd-slicer sets
this.destroyed = truebeforepush(null)at entry EOF; when inflate's backpressure pauses the source near EOF, pipe's drain handler callsresume(), which now no-ops on the destroyed flag. The buffered tail and'end'strand forever, which is why the install promise never settles with zero CPU and no error.Why fixing the app still matters after Node reverts: an approved revert exists for the 24.x line (nodejs/node#63834, unreleased as of today). Once it ships and Electron picks it up, these builds heal with no app change. But the change stays on Node main, 26.1.0+ is already affected, and Node 26 is scheduled to become LTS in October. Any future Electron bundling Node 26.x re-breaks the vendored yauzl 2.x path. Durable options, in rough order of effort:
yauzl.fromBufferfor .mcpb-sized archives, as the isolation matrix above suggests (the BufferSlicer path never touches the broken stream code)- upgrade the vendored stack to yauzl >= 3.3.1 (3.0.0 through 3.3.0 vendor the same fd-slicer bug, fixed in Fix destroy() usage in fd-slicer thejoshwolfe/yauzl#170)
- patched fd-slicer: Fix read stream deadlock on Node >= 24.16 / 26.1 andrewrk/node-fd-slicer#8, usable today via npm override
"fd-slicer": "github:drbarq/node-fd-slicer#fix-read-stream-deadlock-node24"(suite 19/19; yauzl 2.10.0's full suite green on 24.16.0)
And +1 to a
--no-compressionoption inmcpb pack: STORED bundles install on broken and fixed builds alike, and it is the only thing an extension author can ship today that works for every user regardless of which Desktop build they have.@bcherny 👀 🙏
Reacted by carlos seguraReacted by Peter- added a commit that references this issue
on Jun 13, 2026 - added a commit that references this issue
on Jun 14, 2026 Closing for now — inactive for too long. Please open a new issue if this is still relevant.
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.
- locked as resolved and limited conversation to collaborators
on Sep 28, 2026
Preflight Checklist
What's Wrong?
Installing a local
.mcpbextension bundle in Claude Desktop for Windows — via drag-and-drop, Settings → Extensions → "Install Extension…", or double-clicking the file — does nothing: no install preview dialog, no error dialog, no error in the logs.This happens for any archive that contains a deflate-compressed entry whose compressed size exceeds roughly 16 KB. Because the official
@anthropic-ai/mcpbCLI (mcpb pack) always deflate-compresses entries, effectively every realistically-sized locally-built extension is uninstallable on 1.12603.1. Only near-empty bundles (~2 KB payloads) still install.The failure is completely silent, so extension authors have no signal about what's wrong — bundles that are fully valid zips (verified: correct headers, sizes, CRCs;
inflateRawSyncdecompresses every entry) simply appear to be ignored.What Should Happen?
The extension install preview dialog should appear (as it does for tiny bundles and as it did on Desktop 1.11847.5 for the very same bundles), and installation should proceed — or, if the archive is somehow unacceptable, a visible error should be shown instead of an indefinite silent hang.
Error Messages/Logs
Steps to Reproduce
server/index.jsis more than a few tens of KB (e.g. any esbuild-bundled server) and pack it withmcpb pack..mcpbinto Settings → Extensions (or double-click it).Minimal standalone repro of the root cause (no Claude Desktop needed), on Node v24.16.0 — the exact runtime the app reports — with yauzl 2.10.0, mirroring the app's
unzipFile:Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
Claude Desktop 1.11847.5 (same bundles installed fine)
Claude Code Version
Claude Desktop 1.12603.1 (Electron, Node 24.16.0 per
main.logstartup banner)Platform
Other
Operating System
Windows
Terminal/Shell
PowerShell
Additional Information
Root cause analysis
The install preview path in the main process (
handleDxtFile→previewDxtExtension→ the yauzl-basedunzipFile) opens archives withyauzl.open(yauzl 2.x), which streams each entry from disk via fd-slicer and pipes it throughzlib.createInflateRaw(). Under the Node 24.16 runtime bundled with Desktop 1.12603.1, this fd-slicer → zlib pipe deadlocks on backpressure for entries above ~16 KB compressed: zero bytes flow, noerrorfires, no CPU is consumed, and the preview promise never settles — so no dialog and no error path.Isolation matrix (all against the same valid bundle; large entry
csize=1,048,592,usize=4,438,216):yauzl.open+openReadStream(default inflate) — the app's code pathyauzl.open+openReadStream({ decompress: false })(raw, no zlib)yauzl.fromBufferon the same file read into memory (default inflate)zlib.inflateRawSyncon the entry's compressed bytesRaw-streaming OK + in-memory inflate OK + file-streamed inflate hanging + a size threshold pins the fault on the fd-slicer ReadStream ↔ zlib Transform backpressure interaction under Node 24 — not the archive, zip metadata, manifest, or org blocklist/allowlist (all verified clean).
Suggested fixes
yauzl.fromBufferinstead ofyauzl.openin the preview/install path (bundle sizes are already capped by validation), ornode:stream.pipeline-based plumbing) to survive Node 24 backpressure semantics, orWorkaround for extension authors
Pack
.mcpbarchives with stored (method 0, uncompressed) entries; they bypass the inflate pipeline and install correctly on both 1.11847.5 and 1.12603.1. Note this meansmcpb packin@anthropic-ai/mcpbcurrently produces archives the matching Desktop version cannot install — a--no-compressionoption there would help.Reporter: ddmitov@gmail.com · Found 2026-06-12