Skip to content

Windows: npm-global Claude Code install mis-detected as "desktop app", breaking headless memory generation #2723

@MrDea1h

Description

@MrDea1h

Summary

On Windows, a Claude Code CLI installed via npm install -g @anthropic-ai/claude-code is mis-detected as the "desktop app" by src/shared/find-claude-executable.ts, producing the error:

Generator failed {provider=claude, error=Found desktop app at
"C:\Users\<user>\AppData\Roaming\npm\node_modules\@anthropic-ai\claude-code\bin\claude.exe"
but it doesn't support headless mode. Install Claude Code CLI: npm install -g @anthropic-ai/claude-code}

This is self-contradictory: the binary it rejects is exactly what the suggested npm install -g command produces. When it triggers, observation generation fails and memory is lost.

Environment

  • OS: Windows 11 Pro (26200)
  • claude-mem: 13.4.0 (latest; reproduced against current main @ 8463689)
  • Worker runtime: Bun 1.3.14
  • Claude Code: 2.1.158 (used both the VS Code extension's bundled claude.exe and a fresh npm i -g @anthropic-ai/claude-code)
  • CLAUDE_CODE_PATH set to …\AppData\Roaming\npm\node_modules\@anthropic-ai\claude-code\bin\claude.exe

Root cause

Two issues in src/shared/find-claude-executable.ts combine:

1. looksLikeDesktopAppPath() false-positive (confirmed bug).

function looksLikeDesktopAppPath(candidatePath: string): boolean {
  const normalized = candidatePath.replace(/\/g, '/').toLowerCase();
  return (
    normalized.includes('appdata') ||           // <-- matches %AppData%\Roaming\npm
    normalized.includes('program files') ||
    normalized.includes('program files (x86)')
  );
}

npm's global prefix on Windows is %AppData%\Roaming\npm\…, so every npm-global CLI install contains appdata and is classified as a "desktop app". The error message then tells the user to run the very command that put it there.

2. VERSION_CHECK_TIMEOUT_MS = 3000 is too tight (suspected trigger).
The desktop-app branch is only reached when verifyClaudeVersion() returns null, i.e. claude --version didn't finish within 3 s. The native claude.exe is ~225 MB; a cold start on Windows (first run after install, Defender real-time scan) can exceed 3 s. Once warm it is fast, which matches the intermittent nature of the failures (6 occurrences in one session, interleaved with successes).

Evidence the binary is fine (it is not a desktop-only app)

  • claude -p "Reply with: HEADLESS_OK"HEADLESS_OK
  • claude --help lists -p/--print, --output-format, --input-format (full headless surface)
  • execFileSync(claudeExe, ['--version'], { timeout: 3000, stdio: ['ignore','pipe','ignore'] }) returns "2.1.158 (Claude Code)" in ~540 ms under both Node 24 and Bun 1.3.14 (when warm)

So the binary supports headless mode; the detection is wrong.

Impact

  • Intermittent loss of observations on Windows.
  • The error misdirects users to reinstall a CLI they already have, with no path to resolution.

Proposed fix (PR incoming)

  1. In looksLikeDesktopAppPath(), return false for npm/Node CLI locations (paths containing /node_modules/ or a /npm/ segment) before the appdata/program files check.
  2. Raise VERSION_CHECK_TIMEOUT_MS (e.g. to 10 s) so a cold native-binary start isn't mistaken for an unusable binary.

Secondary observations (separate, not in the PR — FYI)

Same machine/session, may warrant their own issues:

  • [PARSER] SDK returned non-XML idle response — ignoring queued batch {outputClass=idle, consecutiveInvalidOutputs=N} repeats 1–3× before a valid <observation> arrives; at N=3 the SDK session is "poisoned" and respawned. Generation eventually succeeds but wastes retries.
  • [CHROMA_MCP] Connection failed … MCP error -32000: Connection closed on every sync (cmd /c uvx --python 3.13 --with "onnxruntime>=1.20" --with "protobuf<7" chroma-mcp==0.2.6 …). Vector search is unavailable on this Windows host; SQLite storage still works (STORED | obsIds=[…]).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions