Skip to content

Windows: subprocess can't launch 'claude' (claude.cmd shim) → WinError 2 kills every auto-save #120

Description

@alanvaco-ctrl

Description

On Windows the auto-save pipeline silently fails because pipeline/haiku.py invokes the CLI in list-form as subprocess.run(["claude", ...]) (no shell=True). The npm global install ships the CLI only as a claude.cmd shim (there is no claude.exe). Python's subprocess goes through CreateProcess, which only resolves .exe from a bare name — so it raises FileNotFoundError: [WinError 2] The system cannot find the file specified.

Every save-session.sh / run-consolidation.sh run dies right after [haiku] calling, so now.md / today-*.md / recent.md are never generated. (The SessionStart hook and /remember skill keep working since they don't spawn claude — consistent with the note in #6.)

This is a 5th Windows bug not covered by the four fixed in #6.

Reproduction

  1. Windows, CLI installed via npm (~/AppData/Roaming/npm/claude.cmd, no claude.exe).
  2. Trigger any auto-save (or run scripts/save-session.sh --force).
  3. Pipeline aborts; .remember/logs/memory-*.log shows the error below.

Minimal repro:

import subprocess, tempfile
subprocess.run(["claude", "--version"], cwd=tempfile.gettempdir())
# FileNotFoundError: [WinError 2] ...
# Works with shell=True, or with the full claude.cmd path from shutil.which("claude").

Expected behavior

Auto-save spawns the CLI and appends a summary to now.md.

Actual behavior

[haiku] calling (branch: main)
[haiku] ERROR: call-haiku error: [WinError 2] El sistema no puede encontrar el archivo especificado

now.md / today-*.md never created.

Suggested fix

Resolve the binary to its full path before spawning. shutil.which("claude") honours PATHEXT, returns the full claude.cmd path, and subprocess launches it fine while still piping the prompt via stdin (no shell=True, no argv-length regression). Cross-platform safe (returns the plain path on Linux/macOS):

import shutil, os

def _resolve_claude_bin() -> str:
    override = os.environ.get("REMEMBER_CLAUDE_BIN", "").strip()
    if override:
        return override
    return shutil.which("claude") or "claude"

# cmd = [_resolve_claude_bin(), "-p", ...]

Verified locally on the env below: 56/56 test_haiku.py pass and save-session.sh --force now writes now.md → compresses to today-*.md.

Environment

  • claude-remember version: 0.8.2
  • Claude Code version: 2.1.100
  • Shell: Git Bash (bash); CLI also present as claude.ps1 / claude.cmd
  • OS: Windows 11 Pro
  • Python version: 3.13.7

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions