Fix claude-code brain on Windows: pass long system prompts via file, not argv - #28
Open
TheMythologist wants to merge 1 commit into
Open
Fix claude-code brain on Windows: pass long system prompts via file, not argv#28TheMythologist wants to merge 1 commit into
TheMythologist wants to merge 1 commit into
Conversation
The harness system prompt (~44K chars) was passed as a single argv value to `claude --system-prompt`, but Windows CreateProcess caps the whole command line at 32767 chars. Python maps that overflow (WinError 206) to errno ENOENT, so it surfaced as FileNotFoundError and the provider mislabelled it "claude CLI not found" — every claude-code brain call failed on Windows regardless of where the binary lived. - `_prompt_flag` inlines prompts up to 8000 chars and writes anything longer to a temp file, handing it over via `--system-prompt-file` / `--append-system-prompt-file` (both accepted by the CLI). - `_run_cli` now wraps `_spawn_cli` and deletes the spilled temp files in a `finally`, so nothing leaks per call. - A WinError 206 spawn failure reports the actual command-line length instead of claiming the binary is missing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Every
claude-codebrain call fails on Windows with a misleading error:The binary is installed, on
PATH, andshutil.which("claude")resolves it correctly — spawning that exact path by hand works fine. The lookup was never the problem.Root cause
_run_clipassed the whole harness system prompt as a single argv value toclaude --system-prompt.compose_system(endpoint, DEFAULT_SYSTEM)is 43,629 characters, and WindowsCreateProcesscaps the entire command line at 32,767 characters. The overflow comes back asWinError 206("The filename or extension is too long"), which CPython maps toerrno 2 / ENOENT— so Python raisesFileNotFoundError, indistinguishable from a missing executable, and the provider'sexcept FileNotFoundErrorbranch reported it as such.Verified directly: spawning
claudewith a 32,000-char argument succeeds; at 33,000 it raisesFileNotFoundError [WinError 206].POSIX is unaffected (
ARG_MAXis ~2 MB there), which is why this stayed hidden.Fix
_prompt_flag()inlines prompts up to_MAX_INLINE_PROMPT(8000 chars) and spills anything longer to a temp file, delivered via--system-prompt-file/--append-system-prompt-file. Both flags are accepted by the CLI (confirmed against 2.1.220)._run_cli()now wraps_spawn_cli()and unlinks every spilled temp file in afinally, so nothing leaks per call. The sink is per-call, so concurrent calls don't clobber each other.WinError 206spawn failure now reports the actual command-line length instead of claiming the binary is missing.Short prompts keep the exact previous argv, so behaviour is unchanged for existing callers and on POSIX. The conversation prompt already went over stdin and was never affected.
Testing
tests/test_claude_code.py: long system prompt spills to a file with matching content; long appended doctrine uses--append-system-prompt-filewhile the operator file still leads; the argv built by a real_run_clicall stays under 32,767 chars and the temp file is deleted afterwards; aWinError 206failure surfaces as "command line too long" rather than "not found".