Skip to content

Windows: Claude Code CLI hits spawn ENAMETOOLONG on long composed prompts (#15 didn't cover Claude) #52

Description

@lefarcen

Symptom

On Windows, sending a non-trivial prompt with Claude Code as the active agent fails with:

spawn failed: spawn ENAMETOOLONG

Reproduced at #51 (user @valkryhx, Node v22.17.0, Windows, claude.CMD v2.1.81 npm-installed at d:\\nodejs\\node_global\\claude.CMD).

Why

Windows CreateProcess caps the combined command line + environment block at ~32 KB. OD composes the system prompt from three layers (base output contract + design-system body + skill body) plus the user message — for non-trivial skills (e.g. magazine-web-ppt / guizang-ppt) the composed prompt easily exceeds the cap.

#15 fixed this class of bug for the other non-Claude CLIs by introducing promptViaStdin: true and piping the composed prompt through child.stdin instead of argv. Codex, Gemini CLI, OpenCode, Cursor Agent, Qwen Code are all stdin-delivery now.

Claude was explicitly excluded (per #15's PR description: "Claude Code is unaffected — it uses the -p argv path plus its own stream-json parser"). The argv path still composes the prompt into argv, so on Windows it hits ENAMETOOLONG once the composed prompt grows past ~32 KB.

The current Claude buildArgs in daemon/agents.js:

buildArgs: (prompt, _imagePaths, extraAllowedDirs = [], options = {}) => {
  const args = [
    '-p',
    prompt,                                    // ← argv prompt; ENAMETOOLONG on Windows for long prompts
    '--output-format', 'stream-json',
    '--verbose',
  ];
  ...
}

Likely fix shape

Either:

A. Add stdin support to the Claude buildArgs. Verify Claude Code CLI accepts the prompt via stdin (e.g. claude -p - or omitting -p and piping). If it does, set promptViaStdin: true on the Claude agent def and drop prompt from argv. The stream-json parsing in daemon/claude-stream.js is independent of how the prompt arrives, so this should be a small change.

B. Temp-file fallback. Write the composed prompt to os.tmpdir() and pass the file path via -p @<path> or a documented Claude flag for file-based prompt.

(A) is preferred — symmetrical with the other agents and the lifetime of the file in (B) is awkward.

Workarounds in the meantime

Repro

  1. Windows + Node ≥ 20 + claude CLI installed via npm-global.
  2. pnpm dev:all, pick Claude as the agent.
  3. Pick magazine-web-ppt (guizang-ppt) skill or any skill with a multi-KB SKILL.md.
  4. Send a normal-length user prompt. Daemon logs spawn ENAMETOOLONG.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions