Why Claude Code fails on Windows when you use multi-line prompts

JulesCrafter Novice 1h ago 144 views 14 likes 2 min read

I've been pushing our team to integrate more LLM agents into our internal triage workflows to replace some of our clunky RPA scripts. We've been running head-to-head evals between different harnesses to see which one actually handles web tasks without hallucinating. I hit a wall where one of our setups was scoring a pathetic 3/24 on tasks that should have been trivial. The weird part? I hadn't changed the model or the prompt wording—I just changed how the prompt was being passed to the process, and the score jumped to 21/24.

The ghost in the machine

We were testing routine web work: filling forms, downloading files, and verifying data. I was using two different setups. One hit the computer use API directly, and the other used Claude Code in headless mode (claude -p) paired with Playwright.

To keep things objective, we used machine verification. We didn't trust the agent's "I'm done" message; we checked the actual JSONL payloads and file sizes. When the headless setup started failing almost every single trial, my first instinct was that the model was just choking on the specific prompt format. I was wrong. The model wasn't the problem—the Windows environment was.

The culprit is the .CMD shim

If you're on Windows and installed Claude Code via npm, you've got a file called claude.CMD sitting on your PATH. When you use Python's subprocess or shutil.which("claude"), Windows resolves to that .CMD file instead of the actual executable.

That file is just a batch wrapper:

"%dp0%\node_modules\@anthropic-ai\claude-code\bin\claude.exe" %*

Here is the catch: when you pass a multi-line prompt through that %* argument forwarder in cmd.exe, everything after the first newline is silently deleted. The agent doesn't get an error; it just receives a truncated prompt. In my tests, the agent would see "Follow the instruction below exactly," and then nothing. Of course, it failed because the actual instructions were on line two.

I put together this snippet to prove it. If you run this, you'll see the shim fails while the direct .exe works:

import os, subprocess

EXE = os.path.join(os.environ["APPDATA"], "npm", "node_modules",
 "@anthropic-ai", "claude-code", "bin", "claude.exe")
CMD = os.path.join(os.environ["APPDATA"], "npm", "claude.CMD")
PROMPT = "Follow the instruction below exactly.\nOutput the string MARKER_TAIL_9137 and nothing else."

for label, argv0 in (("claude.CMD (shim)", CMD), ("claude.exe (direct)", EXE)):
 r = subprocess.run([argv0, "-p", PROMPT], capture_output=True, text=True,
 encoding="utf-8", errors="replace", timeout=180)
 out = (r.stdout or "") + (r.stderr or "")
 print(label, "tail_received =", "MARKER_TAIL_9137" in out)

How to fix your AI workflow

This is a nightmare to debug because there are no crash logs or non-zero exit codes. Everything looks "fine," but your agent is basically operating with amnesia. If you're building a real-world deployment on Windows, you have two options to avoid this:

  • Call the binary directly: Don't trust shutil.which. Explicitly point your code to claude.exe.
  • Flatten your prompts: Replace all newlines with spaces before passing the string to the CLI. This is the safer bet for cross-platform stability.

For anyone doing deep dive prompt engineering, just remember that the "plumbing" between your Python script and the LLM can be just as volatile as the model itself.
pythonWorkflowAI Implementation

All Replies (4)

S
SkylerDev Intermediate 58m ago
Just wrap everything in quotes or enjoy the thrill of random crashes. It's a feature.
0 Reply
C
ChrisPunk Novice 56m ago
Does this happen across all shells or just PowerShell? Curious if it's a line-ending issue.
0 Reply
N
NovaGuru Advanced 54m ago
@ChrisPunk Probably just another case of lazy dev work. Why would it even work on Linux but not Windows?
0 Reply
T
TaylorDreamer Intermediate 52m ago
Had the same issue last week. Switching to a different terminal usually fixes it for me.
0 Reply

Write a Reply

Markdown supported