{"slug": "a-batch-file-shim-was-truncating-my-agent-s-prompts-on-windows-3-24-to-21-24", "title": "A Batch-File Shim Was Truncating My Agent's Prompts on Windows (3/24 to 21/24)", "summary": "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.", "body_md": "Environment: Windows 11 Home, Python 3.x, Claude Code installed via `npm install -g @anthropic-ai/claude-code`\n\n. Measured 2026-08-14 to 2026-08-16.\n\nI 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.\n\nI 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:\n\n`max_turns=40`\n\n), 8 tasks x 1 trial.`claude -p`\n\n) 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.\n\nFirst 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.\n\nOn Windows, when you drive `claude -p`\n\nfrom Python via `subprocess`\n\nand let `shutil.which`\n\nresolve 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.\n\nRoot cause: the npm global install of Claude Code puts a file named `claude.CMD`\n\non PATH. That's the file `shutil.which(\"claude\")`\n\nresolves to — not the real executable. It's a batch wrapper. Its body is:\n\n```\n\"%dp0%\\node_modules\\@anthropic-ai\\claude-code\\bin\\claude.exe\"   %*\n```\n\nLet me separate what I measured from what I'm inferring.\n\nWhat I measured: swapping only `argv[0]`\n\nbetween the two paths changes the outcome. Point it at `claude.CMD`\n\nand the tail is gone; point it at `claude.exe`\n\nand it arrives. Prompt, flags, and environment are identical, so the difference is the shim.\n\nWhat I'm inferring: `%*`\n\nis 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`\n\n, or both). Either workaround below is sufficient without knowing, so I stopped there.\n\nMinimal reproduction:\n\n``` python\nimport os, subprocess\n\nEXE = os.path.join(os.environ[\"APPDATA\"], \"npm\", \"node_modules\",\n                   \"@anthropic-ai\", \"claude-code\", \"bin\", \"claude.exe\")\nCMD = os.path.join(os.environ[\"APPDATA\"], \"npm\", \"claude.CMD\")\nPROMPT = \"Follow the instruction below exactly.\\nOutput the string MARKER_TAIL_9137 and nothing else.\"\n\nfor label, argv0 in ((\"claude.CMD (shim)\", CMD), (\"claude.exe (direct)\", EXE)):\n    r = subprocess.run([argv0, \"-p\", PROMPT], capture_output=True, text=True,\n                       encoding=\"utf-8\", errors=\"replace\", timeout=180)\n    out = (r.stdout or \"\") + (r.stderr or \"\")\n    print(label, \"tail_received =\", \"MARKER_TAIL_9137\" in out)\n```\n\nMeasured result:\n\n`claude.CMD (shim)`\n\n: `tail_received = False`\n\n. The model's reply asks for the missing instruction, having seen only line 1: \"Follow the instruction below exactly.\"`claude.exe (direct)`\n\n: `tail_received = True`\n\n.There are two fixes:\n\n`claude.exe`\n\ndirectly instead of trusting whatever `shutil.which(\"claude\")`\n\nreturns.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.\n\n`--model`\n\nflag 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`\n\nplus 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.\n\nIf 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.", "url": "https://wpnews.pro/news/a-batch-file-shim-was-truncating-my-agent-s-prompts-on-windows-3-24-to-21-24", "canonical_source": "https://dev.to/chikoku_neko/a-batch-file-shim-was-truncating-my-agents-prompts-on-windows-324-to-2124-512k", "published_at": "2026-08-16 16:05:33+00:00", "updated_at": "2026-08-16 16:42:13.259950+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "large-language-models"], "entities": ["Claude Code", "Anthropic", "Windows", "npm", "Playwright"], "alternates": {"html": "https://wpnews.pro/news/a-batch-file-shim-was-truncating-my-agent-s-prompts-on-windows-3-24-to-21-24", "markdown": "https://wpnews.pro/news/a-batch-file-shim-was-truncating-my-agent-s-prompts-on-windows-3-24-to-21-24.md", "text": "https://wpnews.pro/news/a-batch-file-shim-was-truncating-my-agent-s-prompts-on-windows-3-24-to-21-24.txt", "jsonld": "https://wpnews.pro/news/a-batch-file-shim-was-truncating-my-agent-s-prompts-on-windows-3-24-to-21-24.jsonld"}}