Skip to content

Step 1 could not run on Windows at all - #303

Merged
piyushmakhija28 merged 1 commit into
mainfrom
fix/step1-windows-cmdline-limit
Aug 8, 2026
Merged

piyushmakhija28 merged 1 commit into
mainfrom
fix/step1-windows-cmdline-limit

Conversation

@piyushmakhija28

Copy link
Copy Markdown
Collaborator

Found by running the pipeline, not by reading it. Every Step 1 run on Windows died, fell back to the raw task, and left the whole SDLC chain doing nothing — while the run reported OK:

Step 1 prompt_gen_expert_caller ERROR: [WinError 206] The filename or extension
  is too long -- falling back to raw task
Step 1 emitted a structurally questionable orchestration prompt:
  orchestration_prompt is empty
Step 2: Skipping issue creation -- prompt too short (0 chars)
Step 3: Skipping branch creation -- no GitHub issue created

The call graph is passed to prompt_gen_expert_caller as a command-line argument. On this repository it serialises to 1,031,711 characters — 5,527 affected methods and 940 danger zones — against a Windows CreateProcess limit of 32,767. Thirty-one times over.

Introduced 2026-07-25 in 06b0463. Silent for a month, because the fallback logged an ERROR nobody was reading and every downstream step then declined its work politely.

A temp file was the obvious fix and is the wrong one

The receiver already rendered only affected_methods[:10]. Nine hundred kilobytes were being serialised, marshalled across a process boundary, and discarded.

danger_zones it rendered in full — so a faithful transport would put 123 KB of names into every orchestration prompt. 940 entries is not grounding, it is noise, and it alone still exceeds the limit.

The defect is the payload, not the pipe. So the sender caps at ten and sends the true totals alongside:

  • affected_methods — the rendered prompt is byte-identical to before, because the receiver was already truncating
  • danger_zones — now reads showing 10 of 942. This repository's own rule is that a cap must not be silent, and a prompt presenting ten of nine hundred as if they were all asserts something false about the codebase it claims to describe

Fixing the size uncovered a second defect standing behind the first

The analyser yields dicts (fqn, callers_count, callers_count_high_confidence, risk). The receiver did ", ".join(danger_zones) on them, which raises:

TypeError: sequence item 0: expected str instance, dict found

It had never surfaced because the argument never arrived. Fixing only the size would have swapped WinError 206 for a TypeError. _entry_label reads fqn and falls back to str() rather than requiring the key, so a future shape change degrades to an ugly line instead of killing prompt assembly.

Measured, before and after

before after
command line 1,032,492 3,720 (limit 32,767)
orchestration_prompt 0 chars 334,745 chars
prompt_warnings "...is empty" []
Step 2 skipped, 0 ms ran, 14.6 s, reached GitHub

Step 2 now fails on credentials (401 Bad credentials, gh CLI not authenticated) rather than on an empty prompt. That is an environment problem and out of scope here — the point is that it gets far enough to have one.

README, same root cause

--message "..." was documented space-separated in six places. The parser matches on the --message= prefix, so the space form is silently ignored and the pipeline runs with an empty task. Verified:

--message "test task here"   ->  user_message length=0
--message="test task here"   ->  user_message length=14

Two invocations also lacked --invoked-by entirely and would have been refused. I introduced neither — but I carried both forward in yesterday's README pass, having checked that --invoked-by passed the gate and never checked that --message landed.

Also corrects the claim that --invoked-by selects behaviour. It only authorizes; mode is CLAUDE_HOOK_MODE, and the per-command step ranges belong to the plugin dispatcher.

Tests

Twelve, asserting on the size of what is sent rather than only its content — a correctness test would have passed throughout the outage, because the values were right and merely undeliverable. Each is paired: test_the_uncapped_payload_would_not_fit exists so the fitting test cannot pass on a repository that was small enough anyway, and test_the_old_join_would_have_raised_on_these pins the dict defect as real rather than stylistic.

🤖 Generated with Claude Code

Found by running the pipeline rather than by reading it. Every Step 1 run on
Windows died, fell back to the raw task, and left the whole SDLC chain doing
nothing while the run reported OK:

  Step 1 prompt_gen_expert_caller ERROR: [WinError 206] The filename or
    extension is too long -- falling back to raw task
  Step 1 emitted a structurally questionable orchestration prompt:
    orchestration_prompt is empty
  Step 2: Skipping issue creation -- prompt too short (0 chars)
  Step 3: Skipping branch creation -- no GitHub issue created

The call graph is passed to prompt_gen_expert_caller as a command-line argument.
On this repository it serialises to 1,031,711 characters -- 5,527 affected
methods and 940 danger zones -- against a Windows CreateProcess limit of 32,767.
Thirty-one times over. Introduced 2026-07-25 in 06b0463, silent for a month
because the fallback path logged an ERROR nobody was reading and every
downstream step then declined its work politely.

A temp file was the obvious fix and is the wrong one. The receiver already
rendered only affected_methods[:10], so nine hundred kilobytes were being
serialised, marshalled across a process boundary, and discarded. danger_zones it
rendered in FULL, so a faithful transport would have put 123 KB of names into
every orchestration prompt -- 940 entries is not grounding, it is noise, and it
alone still exceeds the limit. The defect is the payload, not the pipe.

So the sender caps at ten and sends the true totals alongside. For
affected_methods the rendered prompt is byte-identical to what the receiver
produced before, because it was already truncating. For danger_zones it now
reads "showing 10 of 942" -- this repository's own rule is that a cap must not
be silent, and a prompt that presents ten of nine hundred as if they were all is
asserting something false about the codebase it claims to describe.

Fixing the size uncovered a second defect standing behind the first. The
analyser yields dicts (fqn, callers_count, callers_count_high_confidence, and
risk for affected methods), and the receiver did ", ".join(danger_zones) on
them, which raises TypeError: sequence item 0: expected str instance, dict
found. It had never surfaced because the argument never arrived. Fixing only the
size would have swapped WinError 206 for a TypeError. _entry_label reads fqn and
falls back to str() rather than requiring the key, so a future shape change
degrades to an ugly line instead of killing prompt assembly.

Measured before and after on this repository:

  command line     1,032,492 -> 3,720 chars   (limit 32,767)
  orchestration_prompt     0 -> 334,745 chars
  prompt_warnings    "empty" -> []
  Step 2                 skip -> ran, 14.6s, reached GitHub

Step 2 now fails on credentials (401 Bad credentials, gh CLI not authenticated)
rather than on an empty prompt. That is an environment problem and out of scope
here; the point is that it gets far enough to have one.

README: `--message "..."` was documented space-separated in six places. The
parser matches on the `--message=` prefix, so the space form is silently
ignored and the pipeline runs with an empty task -- verified: space form gives
user_message length=0, equals form gives 14. Two invocations also lacked
--invoked-by entirely and would have been refused. I introduced neither, but I
carried both forward in yesterday's README pass while checking that
--invoked-by passed the gate and never checking that --message landed.

Also corrects the claim that --invoked-by selects behaviour. It only authorizes;
mode is CLAUDE_HOOK_MODE and the per-command step ranges belong to the plugin
dispatcher.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@piyushmakhija28
piyushmakhija28 merged commit 0e80690 into main Aug 8, 2026
6 checks passed
@piyushmakhija28
piyushmakhija28 deleted the fix/step1-windows-cmdline-limit branch August 8, 2026 03:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant