A Batch-File Shim Was Truncating My Agent's Prompts on Windows (3/24 to 21/24) A developer discovered that on Windows, a batch-file shim for Claude Code truncated multi-line prompts at the first newline, causing an agent harness to score 3/24 on a web-task eval. By pointing directly to claude.exe instead of the claude.CMD wrapper, the score jumped to 21/24. The issue stems from cmd.exe's argument forwarding, which silently drops everything after the first line. Environment: Windows 11 Home, Python 3.x, Claude Code installed via npm install -g @anthropic-ai/claude-code . Measured 2026-08-14 to 2026-08-16. I was comparing two agent harnesses on the same set of web tasks. The first run of harness B scored 3 out of 24. I didn't touch the model and I didn't touch the prompt wording. I changed only how the prompt reached the process, and the score went to 21/24. Here is what was actually broken. I was running an eval to see how well current agents handle routine web work, the kind a triage process would flag as "candidate for RPA." Two harnesses, same 8 tasks: max turns=40 , 8 tasks x 1 trial. claude -p plus Playwright, same model, 8 tasks x 3 trials = 24 runs.Success in both harnesses is decided by machine verification only: submitted form payloads compared against expected JSONL, downloaded files checked for existence and size, answers matched by regex. The agent's own claim of "done" is never trusted as a success signal. First run of harness B: 3/24. Only the first task passed. I assumed the model was the weak link and started digging into what harness B was actually sending it. On Windows, when you drive claude -p from Python via subprocess and let shutil.which resolve the executable, a multi-line prompt gets truncated at the first newline before the process ever sees it. Everything after line 1 is silently dropped. Root cause: the npm global install of Claude Code puts a file named claude.CMD on PATH. That's the file shutil.which "claude" resolves to — not the real executable. It's a batch wrapper. Its body is: "%dp0%\node modules\@anthropic-ai\claude-code\bin\claude.exe" % Let me separate what I measured from what I'm inferring. What I measured: swapping only argv 0 between the two paths changes the outcome. Point it at claude.CMD and the tail is gone; point it at claude.exe and it arrives. Prompt, flags, and environment are identical, so the difference is the shim. What I'm inferring: % is cmd.exe's mechanism for forwarding arguments to the wrapped command, and the newline appears to be lost in that forwarding. I have not isolated which layer drops it cmd.exe's argument expansion, the shell Python interposes when executing a .CMD , or both . Either workaround below is sufficient without knowing, so I stopped there. Minimal reproduction: python 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 Measured result: claude.CMD shim : tail received = False . The model's reply asks for the missing instruction, having seen only line 1: "Follow the instruction below exactly." claude.exe direct : tail received = True .There are two fixes: claude.exe directly instead of trusting whatever shutil.which "claude" returns.This is hard to catch because there's no exception, no non-zero exit code, and no warning anywhere in the pipeline. cmd.exe forwards a truncated string and everything downstream treats it as a normal, well-formed prompt. The only symptom is a low success rate, which looks identical to "the model isn't capable enough for this task." I spent time suspecting the model before I suspected the wrapper. --model flag set and was running on whatever the CLI's default model was, so this result wasn't comparable to harness A, which was pinned to sonnet-5. Confounded comparison, not a usable data point. max turns=40 plus a 600-second timeout; harness B had only the timeout, no turn cap. Part of the 6/8 vs 21/24 gap comes from that difference, so don't read those two numbers as a head-to-head ranking. The claim of this post is the within-harness-B change, 3/24 to 21/24.Success rate is the product of model capability and harness quality, and the two are easy to conflate when the harness fails silently. Before concluding a model can't do a task, I now check four things: is the target URL, path actually present in what gets sent; is the full instruction arriving intact print the exact prompt the process received, and read it — don't assume ; can the agent actually reach whatever files it's supposed to produce or read; are model and stop conditions pinned explicitly on both sides being compared. If I'd taken that first run at face value, I would have reported that Claude Code plus Playwright can't handle routine web work. The cause had nothing to do with the model: a batch file was dropping everything after the first newline.