claude-code - 💡(How to fix) Fix [BUG] Claude in Chrome native host on Windows fails to claim bridge pipe — `ERR_INVALID_ARG_TYPE` from Bun's `node:net.listen` — missing stale-pipe cleanup branch for `win32`

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

Captured stderr from a manual invocation of the native host

Captured by running claude.exe --chrome-native-host directly from PowerShell with stderr redirected. (Chrome swallows stderr when it spawns native messaging hosts, which is why this isn't normally visible.)

[Claude Chrome Native Host] Initializing... [Claude Chrome Native Host] Creating socket listener: \.\pipe\claude-mcp-browser-bridge-<USERNAME> [Claude Chrome Native Host] Socket server error: <CLI bundle code excerpt — see below>

TypeError: Failed to listen at \.\pipe\claude-mcp-browser-bridge-<USERNAME> code: "ERR_INVALID_ARG_TYPE"

  at listen (unknown:1:1)
  at node:net:1339:30
  at listenInCluster (node:net:1423:24)
  at listen (node:net:1331:20)
  at B:/~BUN/root/src/entrypoints/cli.js:9056:1166
  at Promise (unknown:1:11)
  at start (B:/~BUN/root/src/entrypoints/cli.js:9056:1139)
  at B:/~BUN/root/src/entrypoints/cli.js:9056:357
  at u7 (B:/~BUN/root/src/entrypoints/cli.js:128:6952)
  at OCA (B:/~BUN/root/src/entrypoints/cli.js:9056:262)

Bun v1.3.14 (Windows x64 baseline)

MCP layer log (for context — shows the tool round-trips fine; the failure is below the MCP layer)

C:\Users\<USERNAME>\AppData\Local\claude-cli-nodejs\Cache\<PROJECT>\mcp-logs-claude-in-chrome\<TS>.jsonl:

{"debug":"In-process Chrome MCP server started","timestamp":"…","sessionId":"…","cwd":"C:\"} {"debug":"Starting connection with timeout of 30000ms",...} {"debug":"Successfully connected (transport: stdio) in 2166ms",...} {"debug":"Connection established with capabilities: {"hasTools":true,…,"serverVersion":{"name":"Claude in Chrome","version":"1.0.0"}}",...} {"debug":"Calling MCP tool: tabs_context_mcp",...} {"debug":"Tool 'tabs_context_mcp' completed successfully in 212ms",...}

So at the MCP-protocol level everything looks healthy; the failure is in the in-process MCP server's connection to the (non-existent) native host.

Relevant disassembled native-host code

From the Bun-bundled CLI (B:/~BUN/root/src/entrypoints/cli.js), reconstructed approximately:

async function OCA() { return u7("chrome_native_host_run", async () => { tj("Initializing..."); let server = new Jk_(); let stream = new Lk_(); await server.start(); while (true) { let msg = await stream.read(); if (msg === null) break; await server.handleMessage(msg); } await server.stop(); }); }

class Jk_ { mcpClients = new Map(); nextClientId = 1; server = null; running = false; socketPath = null;

async start() { if (this.running) return; this.socketPath = w66(); // returns e.g. "\.\pipe\claude-mcp-browser-bridge-<USERNAME>"

if (A26.platform() !== "win32") {
  // -------- POSIX cleanup branch --------
  let dir = u38();
  await Dh.unlink(dir).catch(() => {});
  await Dh.mkdir(dir, { recursive: true, mode: 0o700 });
  await Dh.chmod(dir, 0o700).catch(() => {});
  try {
    let entries = await Dh.readdir(dir);
    for (let name of entries) {
      if (!name.endsWith(".sock")) continue;
      let pid = parseInt(name.replace(".sock", ""), 10);
      if (isNaN(pid)) continue;
      try { process.kill(pid, 0); }
      catch {
        await Dh.unlink(Xk_.join(dir, name)).catch(() => {});
        tj(`Removed stale socket for PID ${pid}`);
      }
    }
  } catch {}
  // --------------------------------------
}
// NOTE: no equivalent cleanup / takeover branch for Windows.

tj(`Creating socket listener: ${this.socketPath}`);
// …
// server.listen(this.socketPath) → throws ERR_INVALID_ARG_TYPE on Windows when path is in use,
//                                  or the path-shape Bun's listen accepts on Windows is different.

} }

Process / pipe state captured at the moment of failure

ProcessId ParentProcessId Name CreationDate CommandLine


100764 3100 claude.exe 2026-05-12 22:21:00 "C:\Users<USERNAME>.local\bin\claude.exe" --chrome (no claude.exe --chrome-native-host process is alive after the extension reload)

Named pipes: \.\pipe\chrome.nativeMessaging.in.<HEX> ← created by Chrome for the just-spawned (and now-dead) native host \.\pipe\chrome.nativeMessaging.out.<HEX> ← created by Chrome for the just-spawned (and now-dead) native host \.\pipe\claude-mcp-browser-bridge-<USERNAME> ← still alive, presumably held by PID 100764 (claude --chrome)

Native-host parent process tree (from an earlier moment when the host WAS briefly alive)

PID 7348 chrome.exe (background) └── PID 81932 chrome.exe (browser) └── PID 66692 cmd.exe /d /s /c ""…\chrome-native-host.bat" chrome-extension://fcoeoabgfenejglbffodgkkbkcdhcgfn/ --parent-window=0" < \.\pipe\chrome.nativeMessaging.in.<HEX> > \.\pipe\chrome.nativeMessaging.out.<HEX> └── PID 3736 claude.exe --chrome-native-host (exited within ~1s)

Root Cause

  • Chrome successfully spawns the wrapper cmd.exe /d /s /c "...\chrome-native-host.bat ..." with stdin/stdout attached to fresh \\.\pipe\chrome.nativeMessaging.in/out.<HEX> pipes.
  • The wrapper invokes claude.exe --chrome-native-host.
  • claude.exe logs Initializing... and Creating socket listener: \\.\pipe\claude-mcp-browser-bridge-<USERNAME> to stderr.
  • server.listen(...) throws TypeError: ERR_INVALID_ARG_TYPE.
  • The process exits in well under a second. No Windows Event Log entry is generated (it's a clean error path, not a crash).
  • Chrome's native-messaging stdio pipes remain open with no peer, so the extension reports "disconnected."
  • claude-mcp-browser-bridge-<USERNAME> remains in \\.\pipe\ listings (apparently still held by the claude --chrome Claude Code session).
  • The MCP tool round-trips successfully at the Claude Code MCP protocol layer (logged in …\claude-cli-nodejs\Cache\<PROJECT>\mcp-logs-claude-in-chrome\*.jsonl as Tool 'tabs_context_mcp' completed successfully in 212ms) — but the tool body returns the "Browser extension is not connected" error string because the bridge has no connected native host.

Code Example

### Captured stderr from a manual invocation of the native host

Captured by running `claude.exe --chrome-native-host` directly from PowerShell with stderr redirected. (Chrome swallows stderr when it spawns native messaging hosts, which is why this isn't normally visible.)


[Claude Chrome Native Host] Initializing...
[Claude Chrome Native Host] Creating socket listener: \\.\pipe\claude-mcp-browser-bridge-<USERNAME>
[Claude Chrome Native Host] Socket server error: <CLI bundle code excerpt — see below>

TypeError: Failed to listen at \\.\pipe\claude-mcp-browser-bridge-<USERNAME>
 code: "ERR_INVALID_ARG_TYPE"

      at listen (unknown:1:1)
      at node:net:1339:30
      at listenInCluster (node:net:1423:24)
      at listen (node:net:1331:20)
      at B:/~BUN/root/src/entrypoints/cli.js:9056:1166
      at Promise (unknown:1:11)
      at start (B:/~BUN/root/src/entrypoints/cli.js:9056:1139)
      at B:/~BUN/root/src/entrypoints/cli.js:9056:357
      at u7 (B:/~BUN/root/src/entrypoints/cli.js:128:6952)
      at OCA (B:/~BUN/root/src/entrypoints/cli.js:9056:262)

Bun v1.3.14 (Windows x64 baseline)


### MCP layer log (for context — shows the tool round-trips fine; the failure is below the MCP layer)

`C:\Users\<USERNAME>\AppData\Local\claude-cli-nodejs\Cache\<PROJECT>\mcp-logs-claude-in-chrome\<TS>.jsonl`:


{"debug":"In-process Chrome MCP server started","timestamp":"…","sessionId":"…","cwd":"C:\\"}
{"debug":"Starting connection with timeout of 30000ms",...}
{"debug":"Successfully connected (transport: stdio) in 2166ms",...}
{"debug":"Connection established with capabilities: {\"hasTools\":true,…,\"serverVersion\":{\"name\":\"Claude in Chrome\",\"version\":\"1.0.0\"}}",...}
{"debug":"Calling MCP tool: tabs_context_mcp",...}
{"debug":"Tool 'tabs_context_mcp' completed successfully in 212ms",...}


So at the MCP-protocol level everything looks healthy; the failure is in the in-process MCP server's connection to the (non-existent) native host.

### Relevant disassembled native-host code

From the Bun-bundled CLI (`B:/~BUN/root/src/entrypoints/cli.js`), reconstructed approximately:


async function OCA() {
  return u7("chrome_native_host_run", async () => {
    tj("Initializing...");
    let server = new Jk_();
    let stream = new Lk_();
    await server.start();
    while (true) {
      let msg = await stream.read();
      if (msg === null) break;
      await server.handleMessage(msg);
    }
    await server.stop();
  });
}

class Jk_ {
  mcpClients = new Map();
  nextClientId = 1;
  server = null;
  running = false;
  socketPath = null;

  async start() {
    if (this.running) return;
    this.socketPath = w66();                  // returns e.g. "\\.\pipe\claude-mcp-browser-bridge-<USERNAME>"

    if (A26.platform() !== "win32") {
      // -------- POSIX cleanup branch --------
      let dir = u38();
      await Dh.unlink(dir).catch(() => {});
      await Dh.mkdir(dir, { recursive: true, mode: 0o700 });
      await Dh.chmod(dir, 0o700).catch(() => {});
      try {
        let entries = await Dh.readdir(dir);
        for (let name of entries) {
          if (!name.endsWith(".sock")) continue;
          let pid = parseInt(name.replace(".sock", ""), 10);
          if (isNaN(pid)) continue;
          try { process.kill(pid, 0); }
          catch {
            await Dh.unlink(Xk_.join(dir, name)).catch(() => {});
            tj(`Removed stale socket for PID ${pid}`);
          }
        }
      } catch {}
      // --------------------------------------
    }
    // NOTE: no equivalent cleanup / takeover branch for Windows.

    tj(`Creating socket listener: ${this.socketPath}`);
    // …
    // server.listen(this.socketPath) → throws ERR_INVALID_ARG_TYPE on Windows when path is in use,
    //                                  or the path-shape Bun's listen accepts on Windows is different.
  }
}


### Process / pipe state captured at the moment of failure


ProcessId  ParentProcessId  Name        CreationDate          CommandLine
---------  ---------------  ----------  --------------------  -----------------------------------------------
100764     3100             claude.exe  2026-05-12 22:21:00   "C:\Users\<USERNAME>\.local\bin\claude.exe" --chrome
   (no claude.exe --chrome-native-host process is alive after the extension reload)

Named pipes:
  \\.\pipe\chrome.nativeMessaging.in.<HEX>     ← created by Chrome for the just-spawned (and now-dead) native host
  \\.\pipe\chrome.nativeMessaging.out.<HEX>    ← created by Chrome for the just-spawned (and now-dead) native host
  \\.\pipe\claude-mcp-browser-bridge-<USERNAME> ← still alive, presumably held by PID 100764 (claude --chrome)


### Native-host parent process tree (from an earlier moment when the host WAS briefly alive)


PID 7348   chrome.exe (background)
└── PID 81932   chrome.exe (browser)
    └── PID 66692  cmd.exe /d /s /c ""…\chrome-native-host.bat" chrome-extension://fcoeoabgfenejglbffodgkkbkcdhcgfn/ --parent-window=0"
                                       < \\.\pipe\chrome.nativeMessaging.in.<HEX>
                                       > \\.\pipe\chrome.nativeMessaging.out.<HEX>
        └── PID 3736   claude.exe --chrome-native-host    (exited within ~1s)

---

HKCU\Software\Google\Chrome\NativeMessagingHosts\com.anthropic.claude_code_browser_extension
   (Default) = C:\Users\<USERNAME>\AppData\Roaming\Claude Code\ChromeNativeHost\com.anthropic.claude_code_browser_extension.json
HKCU\Software\Chromium\NativeMessagingHosts\com.anthropic.claude_code_browser_extension      ✓ also registered
HKCU\Software\Microsoft\Edge\NativeMessagingHosts\com.anthropic.claude_code_browser_extension ✓ also registered

---

{
  "name": "com.anthropic.claude_code_browser_extension",
  "description": "Claude Code Browser Extension Native Host",
  "path": "C:\\Users\\<USERNAME>\\.claude\\chrome\\chrome-native-host.bat",
  "type": "stdio",
  "allowed_origins": [
    "chrome-extension://fcoeoabgfenejglbffodgkkbkcdhcgfn/"
  ]
}

---

@echo off
REM Chrome native host wrapper script
REM Generated by Claude Code - do not edit manually
"C:\Users\<USERNAME>\.local\bin\claude.exe" --chrome-native-host

---

# 1. Install claude.exe v2.1.140 and authenticate.
# 2. Install the Claude Chrome extension in Google Chrome.
# 3. Sign into claude.ai with the same account in Chrome.
# 4. Start an interactive session that will hold the bridge pipe:
Start-Process -FilePath "$HOME\.local\bin\claude.exe" -ArgumentList "--chrome"

# 5. Confirm the bridge pipe exists:
Get-ChildItem '\\.\pipe\' | Where-Object Name -match 'claude-mcp-browser-bridge'

# 6. Now manually run the native host, the same way Chrome does, and capture stderr:
& "$HOME\.local\bin\claude.exe" --chrome-native-host 2>&1 |
    Tee-Object -FilePath $env:TEMP\claude-nh.log
RAW_BUFFERClick to expand / collapse

Preflight Checklist

  • I have searched existing issues and this hasn't been reported yet
  • This is a single bug report (please file separate reports for different bugs)
  • I am using the latest version of Claude Code

What's Wrong?

On Windows, claude.exe --chrome-native-host (the Chrome Native Messaging host spawned by the Claude browser extension) exits silently within milliseconds of launch. It tries to create a Unix-style "socket listener" on the named pipe \\.\pipe\claude-mcp-browser-bridge-<USERNAME> but server.listen() throws TypeError: ERR_INVALID_ARG_TYPE. The browser extension therefore never has a working channel to Claude Code, and every mcp__claude-in-chrome__* tool call returns the canned "Browser extension is not connected. Please ensure the Claude browser extension is installed and running..." error — even though the extension, the manifest, the native-messaging registry entry, claude.ai login, and the claude --chrome session are all correctly set up.

Inspection of the disassembled CLI code shows the native host has a platform() !== "win32" cleanup branch that unlinks stale Unix sockets before listening. There is no equivalent cleanup branch for Windows, so on Windows the host has to compete for a singleton named-pipe with whichever process spawned first (typically the active claude --chrome session). Whichever process registers second crashes silently.

What Should Happen?

After the extension is reloaded with claude --chrome running:

  • The native messaging host (claude.exe --chrome-native-host) should be spawned by Chrome and remain alive, holding stdin/stdout pipes to Chrome and either holding or connecting to the bridge pipe.
  • mcp__claude-in-chrome__tabs_context_mcp should return a JSON list of open tabs in the user's MCP tab group, creating the group if needed.
  • Subsequent browser tools (tabs_create_mcp, navigate, etc.) should drive the browser.

Error Messages/Logs

### Captured stderr from a manual invocation of the native host

Captured by running `claude.exe --chrome-native-host` directly from PowerShell with stderr redirected. (Chrome swallows stderr when it spawns native messaging hosts, which is why this isn't normally visible.)


[Claude Chrome Native Host] Initializing...
[Claude Chrome Native Host] Creating socket listener: \\.\pipe\claude-mcp-browser-bridge-<USERNAME>
[Claude Chrome Native Host] Socket server error: <CLI bundle code excerpt — see below>

TypeError: Failed to listen at \\.\pipe\claude-mcp-browser-bridge-<USERNAME>
 code: "ERR_INVALID_ARG_TYPE"

      at listen (unknown:1:1)
      at node:net:1339:30
      at listenInCluster (node:net:1423:24)
      at listen (node:net:1331:20)
      at B:/~BUN/root/src/entrypoints/cli.js:9056:1166
      at Promise (unknown:1:11)
      at start (B:/~BUN/root/src/entrypoints/cli.js:9056:1139)
      at B:/~BUN/root/src/entrypoints/cli.js:9056:357
      at u7 (B:/~BUN/root/src/entrypoints/cli.js:128:6952)
      at OCA (B:/~BUN/root/src/entrypoints/cli.js:9056:262)

Bun v1.3.14 (Windows x64 baseline)


### MCP layer log (for context — shows the tool round-trips fine; the failure is below the MCP layer)

`C:\Users\<USERNAME>\AppData\Local\claude-cli-nodejs\Cache\<PROJECT>\mcp-logs-claude-in-chrome\<TS>.jsonl`:


{"debug":"In-process Chrome MCP server started","timestamp":"…","sessionId":"…","cwd":"C:\\"}
{"debug":"Starting connection with timeout of 30000ms",...}
{"debug":"Successfully connected (transport: stdio) in 2166ms",...}
{"debug":"Connection established with capabilities: {\"hasTools\":true,…,\"serverVersion\":{\"name\":\"Claude in Chrome\",\"version\":\"1.0.0\"}}",...}
{"debug":"Calling MCP tool: tabs_context_mcp",...}
{"debug":"Tool 'tabs_context_mcp' completed successfully in 212ms",...}


So at the MCP-protocol level everything looks healthy; the failure is in the in-process MCP server's connection to the (non-existent) native host.

### Relevant disassembled native-host code

From the Bun-bundled CLI (`B:/~BUN/root/src/entrypoints/cli.js`), reconstructed approximately:


async function OCA() {
  return u7("chrome_native_host_run", async () => {
    tj("Initializing...");
    let server = new Jk_();
    let stream = new Lk_();
    await server.start();
    while (true) {
      let msg = await stream.read();
      if (msg === null) break;
      await server.handleMessage(msg);
    }
    await server.stop();
  });
}

class Jk_ {
  mcpClients = new Map();
  nextClientId = 1;
  server = null;
  running = false;
  socketPath = null;

  async start() {
    if (this.running) return;
    this.socketPath = w66();                  // returns e.g. "\\.\pipe\claude-mcp-browser-bridge-<USERNAME>"

    if (A26.platform() !== "win32") {
      // -------- POSIX cleanup branch --------
      let dir = u38();
      await Dh.unlink(dir).catch(() => {});
      await Dh.mkdir(dir, { recursive: true, mode: 0o700 });
      await Dh.chmod(dir, 0o700).catch(() => {});
      try {
        let entries = await Dh.readdir(dir);
        for (let name of entries) {
          if (!name.endsWith(".sock")) continue;
          let pid = parseInt(name.replace(".sock", ""), 10);
          if (isNaN(pid)) continue;
          try { process.kill(pid, 0); }
          catch {
            await Dh.unlink(Xk_.join(dir, name)).catch(() => {});
            tj(`Removed stale socket for PID ${pid}`);
          }
        }
      } catch {}
      // --------------------------------------
    }
    // NOTE: no equivalent cleanup / takeover branch for Windows.

    tj(`Creating socket listener: ${this.socketPath}`);
    // …
    // server.listen(this.socketPath) → throws ERR_INVALID_ARG_TYPE on Windows when path is in use,
    //                                  or the path-shape Bun's listen accepts on Windows is different.
  }
}


### Process / pipe state captured at the moment of failure


ProcessId  ParentProcessId  Name        CreationDate          CommandLine
---------  ---------------  ----------  --------------------  -----------------------------------------------
100764     3100             claude.exe  2026-05-12 22:21:00   "C:\Users\<USERNAME>\.local\bin\claude.exe" --chrome
   (no claude.exe --chrome-native-host process is alive after the extension reload)

Named pipes:
  \\.\pipe\chrome.nativeMessaging.in.<HEX>     ← created by Chrome for the just-spawned (and now-dead) native host
  \\.\pipe\chrome.nativeMessaging.out.<HEX>    ← created by Chrome for the just-spawned (and now-dead) native host
  \\.\pipe\claude-mcp-browser-bridge-<USERNAME> ← still alive, presumably held by PID 100764 (claude --chrome)


### Native-host parent process tree (from an earlier moment when the host WAS briefly alive)


PID 7348   chrome.exe (background)
└── PID 81932   chrome.exe (browser)
    └── PID 66692  cmd.exe /d /s /c ""\chrome-native-host.bat" chrome-extension://fcoeoabgfenejglbffodgkkbkcdhcgfn/ --parent-window=0"
                                       < \\.\pipe\chrome.nativeMessaging.in.<HEX>
                                       > \\.\pipe\chrome.nativeMessaging.out.<HEX>
        └── PID 3736   claude.exe --chrome-native-host    (exited within ~1s)

Steps to Reproduce

Steps to Reproduce (minimal)

This was reproduced repeatedly across multiple browser-restart and CLI-restart cycles. The minimal sequence:

  1. On a Windows 11 machine, install the Claude Code CLI (claude.exe v2.1.140 from the installer).
  2. Install the Claude in Chrome extension (https://claude.ai/chrome) in Google Chrome.
  3. Sign in to claude.ai in Chrome with the same account that Claude Code is authenticated against.
  4. Open PowerShell and run claude --chrome. Let the session reach the prompt.
  5. In Chrome, open chrome://extensions, find the Claude card and click the reload icon.
  6. In the active Claude Code session, call any browser tool, e.g. mcp__claude-in-chrome__tabs_context_mcp.

Observed: Tool call returns the "Browser extension is not connected…" error. No claude.exe --chrome-native-host process is alive after the extension reload, even though Chrome created new \\.\pipe\chrome.nativeMessaging.in/out.<HEX> pipes for the launch.

Variants attempted (all reproduce the same end state):

  • Start claude --chrome first, then open Chrome.
  • Start Chrome first, then claude --chrome.
  • Quit everything, run Stop-Process claude -Force, restart in a specific order.
  • Install the extension in Microsoft Edge Stable instead of Chrome (with claude.ai logged in there).
  • Close all browsers and only run one at a time.

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

No response

Claude Code Version

2.1.140

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

Windows Terminal

Additional Information

Environment

FieldValue
OSWindows 11 Pro, version 10.0.26200
Architecturex64
Claude Code version2.1.140 (Claude Code)
Claude Code binary pathC:\Users\<USERNAME>\.local\bin\claude.exe (binary mtime 2026-05-12 18:29)
Runtime embedded in claude.exeBun v1.3.14 (Windows x64 baseline)
InterfaceClaude Code CLI in PowerShell (claude --chrome)
Terminal emulatorWindows Terminal / PowerShell 5.1
BrowserGoogle Chrome (C:\Program Files\Google\Chrome\Application\chrome.exe) — also tested with Microsoft Edge Stable (C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe) and Chromium build (C:\games\chrome-win\chrome-win\chrome.exe)
Extension IDfcoeoabgfenejglbffodgkkbkcdhcgfn
Extension version installed1.0.70
Plan (account)Claude Pro
Subscription verifiedYes — same account in Chrome's claude.ai tab as in Claude Code OAuth credentials
Session IDc2c42119-7b29-4395-9242-80f5b9fc8a4d
Session PID100764

Configuration verified before diagnosis

All standard prerequisites verified by reading files on disk and the registry. These are NOT the source of the failure but are listed so the developer doesn't have to re-check.

Native messaging host registry

HKCU\Software\Google\Chrome\NativeMessagingHosts\com.anthropic.claude_code_browser_extension
   (Default) = C:\Users\<USERNAME>\AppData\Roaming\Claude Code\ChromeNativeHost\com.anthropic.claude_code_browser_extension.json
HKCU\Software\Chromium\NativeMessagingHosts\com.anthropic.claude_code_browser_extension      ✓ also registered
HKCU\Software\Microsoft\Edge\NativeMessagingHosts\com.anthropic.claude_code_browser_extension ✓ also registered

Native messaging manifest

C:\Users\<USERNAME>\AppData\Roaming\Claude Code\ChromeNativeHost\com.anthropic.claude_code_browser_extension.json:

{
  "name": "com.anthropic.claude_code_browser_extension",
  "description": "Claude Code Browser Extension Native Host",
  "path": "C:\\Users\\<USERNAME>\\.claude\\chrome\\chrome-native-host.bat",
  "type": "stdio",
  "allowed_origins": [
    "chrome-extension://fcoeoabgfenejglbffodgkkbkcdhcgfn/"
  ]
}

Native host wrapper batch file

C:\Users\<USERNAME>\.claude\chrome\chrome-native-host.bat:

@echo off
REM Chrome native host wrapper script
REM Generated by Claude Code - do not edit manually
"C:\Users\<USERNAME>\.local\bin\claude.exe" --chrome-native-host

Side note: the wrapper does not forward arguments (%* is missing) so the extension origin URL Chrome passes (chrome-extension://fcoeoabgfenejglbffodgkkbkcdhcgfn/ --parent-window=0) never reaches claude.exe. This may or may not be intended — origin validation could be done some other way — but it is worth checking. It is not the proximate cause of the bug described here.

Extension manifest

C:\Users\<USERNAME>\AppData\Local\Google\Chrome\User Data\Default\Extensions\fcoeoabgfenejglbffodgkkbkcdhcgfn\1.0.70_0\manifest.json includes the nativeMessaging permission, signed with the pinned key field (so the extension ID is stable across reinstalls/browsers). Looks correct.

Account match

The user's claude.ai session in Chrome is signed in to the same account as Claude Code's OAuth credentials (C:\Users\<USERNAME>\.claude\.credentials.json shows a subscriptionType: "pro" token; the same account profile is visible in chrome://settings and on claude.ai).

Actual Behavior (bug behaviour)

  • Chrome successfully spawns the wrapper cmd.exe /d /s /c "...\chrome-native-host.bat ..." with stdin/stdout attached to fresh \\.\pipe\chrome.nativeMessaging.in/out.<HEX> pipes.
  • The wrapper invokes claude.exe --chrome-native-host.
  • claude.exe logs Initializing... and Creating socket listener: \\.\pipe\claude-mcp-browser-bridge-<USERNAME> to stderr.
  • server.listen(...) throws TypeError: ERR_INVALID_ARG_TYPE.
  • The process exits in well under a second. No Windows Event Log entry is generated (it's a clean error path, not a crash).
  • Chrome's native-messaging stdio pipes remain open with no peer, so the extension reports "disconnected."
  • claude-mcp-browser-bridge-<USERNAME> remains in \\.\pipe\ listings (apparently still held by the claude --chrome Claude Code session).
  • The MCP tool round-trips successfully at the Claude Code MCP protocol layer (logged in …\claude-cli-nodejs\Cache\<PROJECT>\mcp-logs-claude-in-chrome\*.jsonl as Tool 'tabs_context_mcp' completed successfully in 212ms) — but the tool body returns the "Browser extension is not connected" error string because the bridge has no connected native host.

What I've Already Tried

  1. Reload extension in Chrome (chrome://extensions → reload icon on Claude card). Verified new chrome.nativeMessaging.*.<HEX> pipes were created each time. Native host died each time. No fix.
  2. Toggle extension off then on. Same outcome.
  3. Full Chrome restart (close all windows, verify no chrome.exe in Get-Process, reopen). No fix.
  4. Killed all claude.exe helpers (Get-Process claude | Stop-Process -Force), then ran claude --chrome from a fresh PowerShell before opening any browser. Then opened Chrome and reloaded the extension. No fix — same ERR_INVALID_ARG_TYPE.
  5. Reverse order: opened Chrome with extension first, then started claude --chrome afterwards. No fix.
  6. Switched browsers: installed the same extension in Microsoft Edge Stable (native-messaging is registered for Edge in HKCU\Software\Microsoft\Edge\NativeMessagingHosts). Signed in to claude.ai in Edge with the same account, closed and reopened Edge. Edge spawned the native host but it was actually cmd.exe whose grandparent was Google Chrome not Edge — i.e. whichever Chromium-based browser instance was already running ended up servicing the native messaging call. Either way: same failure.
  7. Verified the Chromium build (C:\games\chrome-win\…) extension was not creating a competing native host. It wasn't (no claude.exe child of chromium.exe).
  8. Looked for stale lock/state files in C:\Users\<USERNAME>\.claude\chrome\ — there are none beyond the bat file. Looked for *.lock, *bridge*, *chrome* files; only tasks/*/.lock files (unrelated) and the bat itself.
  9. Looked at Windows Event Log for Application Error, .NET Runtime, and Windows Error Reporting provider entries in the last 30 min mentioning claude — none. This confirms the native host exits cleanly via the JS error path, not via a process crash.
  10. Read MCP debug logs at C:\Users\<USERNAME>\AppData\Local\claude-cli-nodejs\Cache\<PROJECT>\mcp-logs-claude-in-chrome\*.jsonl. Each tabs_context_mcp call is logged as "completed successfully" with a small latency — confirming the failure is not at the MCP layer; the in-process MCP server is finding no connected native host on the bridge.
  11. Manually invoked claude.exe --chrome-native-host from PowerShell (outside Chrome) with stderr redirected — this is what produced the ERR_INVALID_ARG_TYPE stack trace above. This was the diagnostic that finally pinned down the root cause.

Possible Cause / Hypothesis for Claude developers

There are two distinct, possibly compounding issues:

Hypothesis A (primary): Windows is missing the stale-pipe cleanup branch

Jk_.start() in the bundled CLI clearly has a POSIX cleanup branch (platform() !== "win32" → unlink dir, recreate, prune dead-PID .sock files). The Windows path falls straight through to server.listen(this.socketPath). When any other process is already holding \\.\pipe\claude-mcp-browser-bridge-<USERNAME> — for example the active claude --chrome session — listen fails. Two suggested fixes:

  1. Mirror the POSIX takeover semantics on Windows. On Windows the OS auto-cleans pipes when the owning process exits, so the equivalent is "if listen fails because the path is in use, decide whether to (a) connect-as-client to the existing server, or (b) bail out with a clearer error and tell Chrome the host isn't usable right now."
  2. Decide which role owns the pipe. Right now both claude --chrome and claude --chrome-native-host apparently want to be the server. Pick one canonical server (the native host is the natural choice, since Chrome spawns it on demand) and have claude --chrome connect as a client with retry.

Hypothesis B (also worth investigating): Bun-on-Windows net.listen accepts a different argument shape

The error ERR_INVALID_ARG_TYPE is surprising for a string pipe path that looks valid. It is normally what Node throws when listen()'s first arg is null/undefined/wrong-type, not for EADDRINUSE. Possibilities:

  • w66() returns a Buffer or path-like that Bun's win32 net layer rejects, but Node would have accepted.
  • Bun on Windows expects an options object { path: "..." } rather than the bare path string.
  • A regression in Bun v1.3.14's win32 node:net shim.

If A is the underlying cause but the error is being reshaped through Bun's compatibility layer into ERR_INVALID_ARG_TYPE, fixing A would still resolve the user-visible symptom. If B is independent, it should also be fixed because the error message is actively misleading (it implies a programmer error in an arg passed to listen, when it might just be address-in-use).

Wrapper-script argument forwarding (minor; document only)

chrome-native-host.bat does not contain %*, so the extension origin URL Chrome passes (chrome-extension://fcoeoabgfenejglbffodgkkbkcdhcgfn/) and --parent-window=0 are never forwarded to claude.exe. If the host is meant to validate the calling extension origin, this is broken too. Not the proximate cause of the listen failure, but worth fixing in the same pass.

Additional Context

  • The bat file and JSON manifest were generated together (same mtime, 2026-05-12 20:54:42) — apparently when claude --chrome was first invoked on the v2.1.140 build of claude.exe (binary mtime 2026-05-12 18:29). So registration is self-installed by the CLI; the user did not edit it.
  • The Chromium-based browser ecosystem on this machine includes Google Chrome, Microsoft Edge Stable, and a portable Chromium build. All three have com.anthropic.claude_code_browser_extension registered under their respective HKCU\Software\<Browser>\NativeMessagingHosts keys (Chrome, Chromium, Edge). The bug reproduces regardless of which browser is the one with the extension active.
  • The Claude Desktop Electron app (C:\Program Files\WindowsApps\Claude_*\app\Claude.exe) was also running during some of the reproductions. It is unrelated — it does not touch the claude-mcp-browser-bridge-* pipe — but mentioning it here in case it's relevant for ruling out conflicts.
  • The user's PowerShell session is PowerShell 5.1 (Windows PowerShell, not pwsh 7). Claude Code's CLI runs fine but is launched via the standard claude shim.
  • The user has a Pro Claude.ai subscription. Both browser and CLI are signed in to the same account. There is no SSO/identity mismatch.
  • Anonymization in this report: <USERNAME> substitutes the actual Windows username; <HEX> substitutes Chrome's native-messaging pipe-instance hash; <PROJECT> substitutes the cwd-mangled project directory name under claude-cli-nodejs\Cache\; <TS> substitutes ISO-8601 log filenames. The extension ID and Claude Code version are not anonymized because they are public/non-identifying.

Suggested Repro Tester for Anthropic

A minimal Windows VM reproduction:

# 1. Install claude.exe v2.1.140 and authenticate.
# 2. Install the Claude Chrome extension in Google Chrome.
# 3. Sign into claude.ai with the same account in Chrome.
# 4. Start an interactive session that will hold the bridge pipe:
Start-Process -FilePath "$HOME\.local\bin\claude.exe" -ArgumentList "--chrome"

# 5. Confirm the bridge pipe exists:
Get-ChildItem '\\.\pipe\' | Where-Object Name -match 'claude-mcp-browser-bridge'

# 6. Now manually run the native host, the same way Chrome does, and capture stderr:
& "$HOME\.local\bin\claude.exe" --chrome-native-host 2>&1 |
    Tee-Object -FilePath $env:TEMP\claude-nh.log

Expected output: TypeError: Failed to listen at \\.\pipe\claude-mcp-browser-bridge-<USERNAME> with code: "ERR_INVALID_ARG_TYPE".

Severity / Impact

Hard blocker for "Claude in Chrome" on Windows. Every browser tool (tabs_context_mcp, tabs_create_mcp, navigate, get_page_text, javascript_tool, gif_creator, etc.) returns the canned "not connected" error, regardless of correct setup. The user cannot use the feature at all until this is fixed upstream.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix [BUG] Claude in Chrome native host on Windows fails to claim bridge pipe — `ERR_INVALID_ARG_TYPE` from Bun's `node:net.listen` — missing stale-pipe cleanup branch for `win32`