[BUG] /desktop fails on Windows - "Failed to open Claude Desktop" despite app being installed and running

Status Closed — duplicate
Reported on v2.1.143
Maintainer reply None cached
Activity 11 comments · opened May 16, 2026 · closed Aug 25, 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?

The /desktop command in Claude Code CLI always fails with "Failed to open Claude Desktop. Please try opening it manually." even though Claude Desktop is fully installed and running.

What Should Happen?

/desktop should detect Claude Desktop and open it successfully.

Error Messages/Logs

> /desktop
Error: Failed to open Claude Desktop. Please try opening it manually.

Steps to Reproduce

  1. Install Claude Desktop on Windows 11 (fresh install)
  2. Verify Claude Desktop opens manually - it works fine
  3. Open Claude Code CLI
  4. Type /desktop
  5. Error appears every time

Claude Model

None

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2.1.143 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

  • AnthropicClaude folder exists at correct path
  • claude.exe found at: %LOCALAPPDATA%\AnthropicClaude\app-1.7196.1\claude.exe
  • Claude Desktop runs fine manually (10 processes visible in Task Manager)
  • Tried creating symlink at %LOCALAPPDATA%\AnthropicClaude\claude.exe - did not help
  • Tried CLAUDE_DESKTOP_PATH environment variable - did not help
  • Reinstalled Claude Desktop multiple times - same result every time

View original on GitHub ↗

9 Comments

github-actions[bot] · 3 months ago

Found 2 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/59692
  2. https://github.com/anthropics/claude-code/issues/36079

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

jshaofa-ui · 3 months ago

claude-code #59824 — /desktop Fails on Windows

Issue

URL: https://github.com/anthropics/claude-code/issues/59824
Title: /desktop fails on Windows — "Failed to open Claude Desktop" despite app installed
Severity: Medium — desktop integration broken
Labels: bug, platform:windows, area:cli, area:desktop
Affects: Windows users trying to open Claude Desktop from CLI

Root Cause Analysis

The /desktop command fails to detect Claude Desktop on Windows even when it's installed and running. This is a regression — it worked in a previous version.

  1. Registry key path changed: Claude Desktop may have changed its Windows registry location
  2. Process detection method changed: The method for detecting running Claude Desktop processes may be broken
  3. Protocol handler issue: The claude:// or claude-desktop:// protocol handler may not be registered
  4. Path resolution changed: The executable path detection may have changed

Proposed Fix

// src/commands/desktop.ts
const findClaudeDesktop = async (): Promise<string | null> => {
  // Method 1: Check registry (Windows)
  const registryPath = await checkRegistry();
  if (registryPath) return registryPath;
  
  // Method 2: Check common install locations
  const commonPaths = [
    path.join(process.env.LOCALAPPDATA || '', 'Programs', 'Claude Desktop', 'Claude Desktop.exe'),
    path.join(process.env.LOCALAPPDATA || '', 'claude-desktop', 'Claude Desktop.exe'),
    path.join(process.env.APPDATA || '', 'Claude Desktop', 'Claude Desktop.exe'),
    'C:\\Program Files\\Claude Desktop\\Claude Desktop.exe',
    'C:\\Program Files (x86)\\Claude Desktop\\Claude Desktop.exe',
  ];
  
  for (const p of commonPaths) {
    if (fs.existsSync(p)) return p;
  }
  
  // Method 3: Check running processes
  const runningProcess = await findRunningProcess();
  if (runningProcess) return runningProcess;
  
  // Method 4: Check protocol handler
  const protocolApp = await checkProtocolHandler('claude-desktop://');
  if (protocolApp) return protocolApp;
  
  return null;
};
const openClaudeDesktop = async (): Promise<void> => {
  if (process.platform === 'win32') {
    // Try protocol handler first (most reliable on Windows)
    try {
      await execa('start', ['claude-desktop://'], { shell: true });
      return;
    } catch {
      // Fall back to executable
    }
    
    // Try finding and launching the executable
    const exePath = await findClaudeDesktop();
    if (exePath) {
      await execa('start', ['""', exePath], { shell: true });
      return;
    }
  }
  
  throw new Error('Failed to open Claude Desktop. Please try opening it manually.');
};
// /desktop --diagnose
const diagnoseDesktop = async () => {
  console.log('Claude Desktop Diagnostic:');
  console.log(`Platform: ${process.platform}`);
  console.log(`Registry check: ${await checkRegistry() || 'not found'}`);
  console.log(`Common paths:`);
  // ... check each path
  console.log(`Running processes: ${await findRunningProcess() || 'none'}`);
  console.log(`Protocol handler: ${await checkProtocolHandler('claude-desktop://') || 'not registered'}`);
};

Impact

  • Windows users can open Claude Desktop from CLI again
  • Diagnostic mode helps troubleshoot future issues
  • Multi-method detection is more robust than single-method
Slimand · 3 months ago

Update: After adding HKLM registry entry with the shim executable, /desktop now opens Claude Desktop successfully. However it then shows "CLI session transcript not found: <session-id>".

Investigation shows a path mismatch:

  • CLI stores sessions in: C:\Users\slima\.claude\sessions\
  • Desktop looks for them in: %APPDATA%\Roaming\Claude\local-agent-mode-sessions\

These are completely different paths and formats. The CLI uses simple files like "29056.json" while Desktop expects a folder structure with manifest.json inside.

So there are actually two separate bugs:

  1. /desktop not detecting Claude Desktop installation (partially fixed with HKLM registry workaround)
  2. Session transcript path mismatch between CLI and Desktop app

i think that Both need to be fixed on Anthropic's side.

Baouse · 3 months ago

Confirming this bug is still present on the latest Claude Code and Claude Desktop as of 2026-05-25 — over a week after #61194 was filed and auto-closed as a duplicate of this thread.

Environment

  • OS: Windows 11 Home 10.0.26200
  • Claude Code: 2.1.150 (native install)
  • Claude Desktop: MSIX package Claude_1.8555.2.0_x64__pzs8sxrjxfjjc (installed via the .exe installer from https://claude.ai/download — which delivers as MSIX)
  • Shell: PowerShell 7

Symptom
/desktopError: Failed to open Claude Desktop. Please try opening it manually.

Verified working alternatives on the same machine (so install + protocol handler are healthy, the CLI launcher is the broken piece):

  • Start-Process "claude://" → opens the app
  • Start-Process "shell:AppsFolder\Claude_pzs8sxrjxfjjc!Claude" → opens the app
  • Start menu shortcut → opens the app

The MSIX-aware diagnosis in this issue still matches current behaviour exactly. The official installer at https://claude.ai/download continues to deliver Claude Desktop as an MSIX package, so every new Windows install hits this immediately on first /desktop.

nitzan-blink · 2 months ago

having the same issue on Windows. can't move sessions to the desktop app.

ndwuhuangwei · 2 months ago

Root cause found (for at least a subset of reports here): bare cmd resolution failure with session-lifetime negative cache — same defect class as #67156, different symptom

TL;DR: On Windows, /desktop launches the deep link by spawning the bare command name "cmd". That name goes through an internal resolver that runs where.exe and permanently caches a null result for the whole session if where.exe ever exits 1. Once that happens, every /desktop in the session returns a fabricated exit code 127 without ever spawning anything, and the user sees the generic "Failed to open Claude Desktop. Please try opening it manually." — even though the Desktop app, the claude:// protocol handler, and the deep-link mechanism are all perfectly healthy. This is exactly the mechanism documented in #67156 for bare "git" in ExitWorktree; /desktop is a second symptom surface of the same defect.

Environment (forensics machine)

  • Windows 11 Pro (10.0.22631), no third-party AV, no ASR rules
  • Claude Code 2.1.173 (native installer, ~\.local\bin\claude.exe); failures observed on 2.1.17x, all code excerpts below decompiled from the shipped 2.1.173 binary
  • Claude Desktop 1.11847.5.0, MSIX/Store install (Claude_…_pzs8sxrjxfjjc), claude: protocol declared in the package manifest and registered under HKCU:\Software\Classes\claude

The code path (2.1.173 bundle, minified names as found)

/desktop orchestration (Ai_):

async function Ai_(){let H=S8(),q=await r1K();          // detect via F6("reg",["query","HKEY_CLASSES_ROOT\\claude","/ve"])
  if(q.status==="not-installed")return{success:!1,error:"Claude Desktop is not installed. ..."};
  ...
  let K=Xk5(H);                                          // claude://resume?session=<id>  (single param — see version note below)
  if(!await Lk5(K))return{success:!1,error:"Failed to open Claude Desktop. Please try opening it manually.",deepLinkUrl:K};

The launcher spawns bare "cmd":

async function Lk5(H){N(`Opening deep link: ${H}`);
  {let{code:K}=await F6("cmd",["/c","start","",H]);return K===0}}

F6Iq resolves bare names through egHx7q before spawning:

function x7q(H){let q=C7q.get(H);if(q!==void 0)return q;          // session-lifetime cache, including cached null
  let $=ZFK.join(K,"System32","where.exe");
  try{let f=LFK.execFileSync($,[H],{timeout:5000,env:process.env,...})...
  }catch(_){if(yI4(_))C7q.set(H,null);return null}}                // where.exe exit 1 → null cached for the lifetime of the process

and Iq fabricates a result without spawning anything when resolution returns null:

let j=egH(H);
if(j===null)return Promise.resolve({stdout:"",stderr:`Command '${H}' not found or is in an unsafe location (current directory)`,code:127,...});

127 !== 0Lk5 returns false → the generic error above. This is byte-for-byte the same resolver/cache/fabrication chain as #67156 (x7q/C7q/Iq/egH in 2.1.173 ≡ ag6/og6/Jq/Wm8 in the 2.1.146/2.1.150 bundles analyzed there), confirming the defect is still present in the latest release.

The differential fingerprint that pins it

The same /desktop invocation resolves two bare names: "reg" (detection) and then "cmd" (launch). On the affected session, the user-visible error was "Failed to open…", not "Claude Desktop is not installed…" — meaning where.exe reg succeeded seconds (or milliseconds) before where.exe cmd allegedly failed, in the same process with the same PATH. Both binaries live in System32. A live environment in which reg resolves and cmd does not, simultaneously, does not exist — but a stale negative cache entry for "cmd", poisoned at some earlier moment of the session (one transient where.exe exit-1, e.g. during a momentary PATH anomaly at startup), reproduces exactly this asymmetry, instantly and for the rest of the session.

Forensic timeline (one affected session, four failures)

| Event (UTC, from session transcript / Desktop main.log) | Result |
|---|---|
| 15:02:50 /desktop | "Failed to open Claude Desktop" |
| 15:02:58 /desktop (retry) | same error |
| 15:03:12 Desktop app started manually, protocol handlers (re)registered | — |
| 15:03:30 /desktop — 18 s after Desktop startup, registration fresh, app running | same error |
| 18:15:56 /desktop (hours later, app still running) | same error |

Across all four failures, Desktop's main.log contains zero deep-link arrivals and Windows Defender logged zero blocks — the launch never spawned, consistent with the fabricated-127 path and inconsistent with every registry/MSIX/activation theory.

What was ruled out (verified working on the same machine)

  • The exact failing command cmd /c start "" claude://resume?session=<id> was replayed with identical argv from PowerShell and from Node (child_process.spawnSync, same libuv backend), with the project directory on a secondary drive and windowsHide both on and off: exit 0 in all six combinations, and each link's arrival is visible in Desktop's main.log (Resume deep link: missing or invalid session { sessionId: '<test-id>' }).
  • MSIX install is detected fine in 2.1.173 (detection is reg query HKEY_CLASSES_ROOT\claude, which the Store package satisfies) — so the %LOCALAPPDATA% path shims from #59692/#59883 address a code path that no longer exists.
  • cmd.exe AutoRun, claude:// registration staleness across an MSIX auto-update, AV interference: all checked, all inert.

Version note re #65996

#65996 correctly identified an ampersand-splitting bug in 2.1.168, where the deep link was claude://resume?session=…&cwd=…. In the 2.1.173 bundle the only resume-link builder is new URL("claude://resume"); searchParams.set("session", H) — the cwd parameter is gone and the URL contains no &, so that failure mode appears to have been silently fixed. /desktop failures persisting on ≥2.1.173 are therefore a different bug — the one described here.

Suggested fixes (aligned with #67156)

  1. Don't resolve cmd through PATH at all. The resolver already builds an absolute path for where.exe itself (%SYSTEMROOT%\System32\where.exe); spawn %SYSTEMROOT%\System32\cmd.exe (or %COMSPEC%) the same way. PATH lookup for a fixed system binary adds failure modes and zero value. (Better yet: open the URL via a native ShellExecute equivalent and skip cmd entirely — that would also have prevented the #65996 class.)
  2. Never cache negative resolutions for the process lifetime — retry on next call, or add TTL/invalidation (same proposal as #67156).
  3. Surface the real error. The fabricated result already carries Command 'cmd' not found or is in an unsafe location in stderr, and the failure object already carries deepLinkUrl — showing either of these instead of the generic message would have made this diagnosable from the first report, and gives users a copy-pasteable manual fallback.

Workarounds for affected users (no shims, no registry edits)

  1. Start a fresh CLI session (new process = empty resolver cache) and run /desktop again; or
  2. Open the deep link manually: Win+Rclaude://resume?session=<your-session-id> (session id via /status). This is exactly what /desktop would have launched.
craigvc · 2 months ago

+1, reproducing on Windows 11 with Claude Code 2.1.186 (so still broken past 2.1.143).

In my case the root cause looks broader than the versioned-subfolder path discussed above. I have Claude Desktop installed from the Microsoft Store (MSIX), not the standalone installer — so %LOCALAPPDATA%\AnthropicClaude\ does not exist at all on my machine. Desktop runs fine; it just lives at:

C:\Program Files\WindowsApps\Claude_1.14271.0.0_x64__pzs8sxrjxfjjc\app\Claude.exe
  • Package family name: Claude_pzs8sxrjxfjjc
  • AppId: Claude
  • No app-execution alias is registered (nothing in %LOCALAPPDATA%\Microsoft\WindowsApps), so there is no claude.exe/Claude.exe shim to call by name.

/desktop appears to only probe the standalone %LOCALAPPDATA%\AnthropicClaude\…\claude.exe path, with no fallback for Store/MSIX installs — which can't be launched by raw exe path anyway (they need explorer.exe shell:AppsFolder\Claude_pzs8sxrjxfjjc!Claude, or a registered URL/protocol handoff). So on a Store install /desktop can never succeed. The symlink and CLAUDE_DESKTOP_PATH workarounds in this thread don't apply, since there's no standalone exe to point at.

Use case, for context: I'm not trying to merely launch the app (that works) — I'm trying to transfer/continue my CLI session in Desktop's Claude Code, and /desktop is the only entry point for that handoff.

Suggested fix: detect the MSIX install (e.g. Get-AppxPackage Claude*, package family Claude_pzs8sxrjxfjjc) and launch via shell:AppsFolder\<PackageFamilyName>!<AppId> or a claude://-style protocol handoff, rather than assuming the standalone AnthropicClaude\…\claude.exe path exists.

craigvc · 2 months ago

Follow-up — I switched from the Store/MSIX build to the standalone installer and ruled out every environmental cause, and /desktop still fails. Data points (Windows 11, Claude Code 2.1.186):

  • Standalone Claude Desktop installed → claude.exe is now at

%LOCALAPPDATA%\AnthropicClaude\app-1.14271.0\claude.exe
(plus the stub at %LOCALAPPDATA%\AnthropicClaude\claude.exe).

  • The claude:// URL protocol handler is registered:

HKCU\Software\Classes\claude\shell\open\command"…\AnthropicClaude\app-1.14271.0\claude.exe" "%1"

  • Claude Desktop is installed, launched, and running (verified the processes).
  • /desktop still returns: Failed to open Claude Desktop. Please try opening it manually.

So it isn't the install path, the protocol registration, or Desktop being closed — with all three satisfied it still fails. The failure is in the CLI's /desktop launch logic itself on Windows. (Reported as a regression — it worked in an earlier version.) Hope that narrows it down for whoever picks this up.

dieseld23 · 1 month ago

I had this same issue. I fixed it by going into the registry, HKCU\Software\Classes\claude. I had (Default) and URL Protocol listed there. But only (Default) had data, URL:claude. I put URL:claude as the value for URL Protocol.
Worked after a restart of claude cli

Showing cached comments. Read the full discussion on GitHub ↗