Two Slashes Killed Our Terminals (Godmode+ Found It First Try)
>> The symptom: Every spawned Windows Terminal tab opened as a dead cmd.exe window. No Claude Code. Useless terminal.>> The fake bug: We thought it was claude -p print mode. Rewrote the helper. Still broken.>> The real bug: Git Bash used to defang //c → /c when passing to native exes. It doesn't anymore. cmd saw a literal //c, didn't recognise the switch, dropped to interactive mode.>> The fix: MSYS2_ARG_CONV_EXCL='/c' wt.exe ... -- cmd /c <launcher>. Two characters changed. Verified in one smoke test.>> How Godmode+ won: Phase 5's smoke test — "verify the build actually works" — surfaced the real root cause that hours of manual debugging had missed.
The symptom: every new tab was DOA
Every time one of our scripts spawned a new Windows Terminal tab, the tab opened as a black window with the cmd banner. The prompt text we'd written sat below it, dangling like someone had typed it but never pressed Enter.
No Claude TUI. No prompt box. No way to interact. A perfectly useless terminal.
Think of it like a car that turns on but never starts the engine. The dashboard lights come on. The radio plays. But nothing moves. You can't tell from the outside that the engine never engaged — you can only tell because the car isn't driving.
The spawn chain: how a terminal SHOULD be born
Spawning a fresh Claude Code session in Windows is a four-step relay. Each step hands off to the next process, and any link can break.
First hypothesis: blame claude -p
The original helper had a default branch that invoked claude -p <prompt> — "print mode." Print mode runs claude, prints the response to stdout, and exits.
That's exactly what produces a dead terminal: claude prints, exits, bash falls through, the tab parks at a dead shell with the response text on screen. Open and shut. Obvious culprit.
So we rewrote the helper. Removed the print-mode branch. Made every spawn use interactive claude. Shipped the change.
Then Godmode+ ran the smoke test.
Phase 5: the smoke test refused to nod along
Godmode+ runs in phases. Build is phase 2. Smoke test — "verify the deliverable actually works in the real environment" — is phase 5. It's the phase that exists specifically to catch builds that looked done.
The smoke test spawned a tab via the fixed helper, took a screenshot, and asked the obvious question. Is there a Claude TUI rendered in that screenshot? There was not.
This is the moment a normal "ship it" workflow ships it. Type-check passed. Lint passed. The diff looked sensible. But the spawned tab was dead, and only an actual spawn-and-screenshot would prove it.
Without phase 5, this bug ships. The whole point of Godmode+ is that "the code compiles" is not the same as "the feature works." A smoke test is cheap. A user discovering the bug in production is not.
Follow the process tree
When a build looks healthy but the output is wrong, the next move is forensics on the process tree. What's actually alive in that tab? What died?
The process tree showed cmd alive. Stuck. Not running anything. We ran the launcher .cmd file by hand to see what cmd was actually doing — and watched cmd open and drop straight into interactive mode. As if no command had been passed.
Which is exactly what was happening.
The real bug: MSYS ate the slashes
The helper invoked the tab with cmd //c <launcher.cmd>. The double-slash is supposed to be a Git Bash idiom: pass //c through, and MSYS converts it to /c when handing off to the native Windows exe. That way cmd sees its /c switch ("run this and exit") and MSYS doesn't path-mangle the leading slash into C:/.
That defang stopped firing in the current Git Bash binary. //c now passes through literally. cmd received //c as its first argument, didn't recognise it as a switch, and fell through to interactive mode — cmd's default when given no command.
passes
receives
The MSYS layer used to chew the extra slash. It doesn't anymore. There's a way to tell it to step aside.
Once the diagnosis was named, the same flavour of bug showed up elsewhere — taskkill //F //T //PID in the auto-close watcher, schtasks //run //tn in the layout helper, the same pattern in handover-go.sh. None of those switches were firing either.
The fix: two characters and an env var
The patch is small. The reasoning behind the patch is the part you have to write down so future you understands why.
Same pattern applied to the watcher's taskkill /F /T /PID, the layout helper's schtasks /run /tn, and the matching code in handover-go.sh (the auto-handover spawn path — same MSYS layer, same defang failure).
How Godmode+ caught it
This bug had survived multiple sit-down debugging sessions. The first rewrite (removing claude -p) wasn't wrong — print mode was a real footgun — but it wasn't the active cause of the dead-terminal symptom. The active cause was the MSYS defang. We just couldn't see it without spawning an actual tab and inspecting what cmd received.
Godmode+'s protocol forces that inspection. The phases are non-negotiable:
[1] Recon — map every spawn path
↓
[2] Build — rewrite the helper, drop the print branch
↓
[3] Check — static review, type-check
↓
[4] Test — unit-level, no actual spawn yet
↓
[5] Smoke — spawn it for real, screenshot it, verify the TUI loads
↓
[6] Harden — patch the actual root cause
↓
[7] Verify — re-run the smoke test, confirm the tab boots and auto-closes
Build stats
Receipt, not a brag. Here's what Godmode+ actually spent finding and shipping the fix.
| Metric | Value |
|---|---|
| Tool | godmode-plus (continuation) |
| Time taken | 41m 36s (initial run) + ~25m verification |
| Assistant turns | 170 |
| Total tokens | 21.5M (20.9M cache read, 414K cache create) |
| Output tokens | 167,656 |
| Estimated cost | $51.85 USD (Opus rates) |
| Files changed | claude-tab.sh, handover-go.sh, spawn-agent SKILL.md, two memory entries |
| Bugs found by smoke test | 1 (the one that mattered) |
| Verdict | Shipped |
The honest trade-off: a previous (non-Godmode+) attempt had spent significant time on the wrong root cause. The "first try" in this post's headline refers to Godmode+'s first try — phase 5 caught the bug on the first smoke test it ran.
Why this bug was so sneaky
Silent failure
cmd didn't error on unknown //c. It just opened an interactive prompt — cmd's default with no command. No exit code, no log line, no red flag.
Windows-only
The MSYS layer only exists on Windows. Code reviewed on Mac/Linux looks perfect. The bug only fires in the exact env where it bites.
Version drift
The //c defang DID work in older Git Bash. A binary upgrade changed the conversion rules silently. No release note flagged it.
Stale folklore
Every Windows-bash tutorial online still recommends //c. The advice was right in 2015 and quietly stopped being right.
What changed in our scripts
Do
Use MSYS2_ARG_CONV_EXCL='/c' cmd /c <file> when invoking cmd from Git Bash. Same idea for taskkill, schtasks, and any native exe that takes /flag switches. Exclude only what you need.
Don't
Don't trust the //flag double-slash defang. It's brittle. It depends on which MSYS build you have. It can break on a Git Bash update with no warning and no log.
The lesson is not "MSYS is bad." The lesson is that a build can pass review, compile, and look correct, and still be broken in the one environment that matters. A smoke test is the difference between catching that yourself and finding out from a user.
Run your own max-effort protocol
Godmode+ runs the seven-phase protocol on any task you point it at — recon, build, check, test, smoke, harden, verify. The phase that catches "looks fine, isn't fine" is built in.
Get Godmode+ More post-mortems