Skip to content

Windows regression: explicit Git Bash exec_command.shell falls back to cmd.exe #40328

Description

@Lambholl

What version of the Codex App are you using (From “About Codex” dialog)?

26.818.41509 / codex-cli 0.149.1

What subscription do you have?

Pro 20x

What platform is your computer?

Microsoft Windows NT 10.0.26100.0 x64

What issue are you seeing?

This is a regression in the CLI core embedded in Codex Desktop on native Windows. An exec_command call can provide an absolute Git Bash executable in the shell field, but with embedded CLI 0.149.0-alpha.4.1 the command is executed by cmd.exe instead.

The same absolute shell path worked in a closer rollout using embedded CLI 0.148.0-alpha.21:

Rollout evidence Embedded CLI Result
rollout-2026-08-21T16-20-45-01a02368-7ce7-7e90-9487-6630fadf44ad.jsonl 0.148.0-alpha.21 Bash builtin printf, rg, and sed execute successfully through C:\Program Files\Git\bin\bash.exe
rollout-2026-08-24T11-29-28-01a031d0-e351-7241-80ab-cd8ba21c7709.jsonl 0.149.0-alpha.4.1 The same shell path produces -d was unexpected at this time. from cmd.exe
rollout-2026-08-24T11-33-24-01a031d4-7e07-7cf2-8e01-66b0cc07cbbf.jsonl 0.149.0-alpha.4.1 Four Git Bash path/login variants all produce 'printf' is not recognized...
rollout-2026-08-18T09-49-17-01a0128f-01c0-7380-90e5-bd5c2c65a168.jsonl 0.148.0-alpha.9 Earlier corroboration: wc and sed also execute successfully through the same shell path

For example:

const r = await tools.exec_command({
  cmd: "printf 'BASH=%s\\n' \"$BASH_VERSION\"",
  workdir: "D:/path/to/repo",
  shell: "C:/Program Files/Git/bin/bash.exe",
  login: false
});
text(r.output);

Actual output:

'printf' is not recognized as an internal or external command,
operable program or batch file.

A second Bash-only command produces a characteristic cmd.exe parser error:

const r = await tools.exec_command({
  cmd: "pwd && if [ -d . ]; then echo MEMORY_PRESENT; else echo MEMORY_MISSING; fi",
  workdir: "D:/path/to/repo",
  shell: "C:\\Program Files\\Git\\bin\\bash.exe"
});
text(r.output);

Actual output:

-d was unexpected at this time.

Git Bash itself is installed and functional. Both of these files exist:

C:\Program Files\Git\bin\bash.exe
C:\Program Files\Git\usr\bin\bash.exe

Launching the first executable directly from PowerShell with a .sh script succeeds:

BASH_VERSION=5.3.15(1)-release
PWD=/d/path/to/repo
BASH_CONDITIONAL=ok

The problem occurs when bash is not resolvable by bare name from the Codex process PATH; where.exe bash returns no match. The explicit absolute shell path should make that irrelevant, but Codex appears to discard it and silently selects cmd.exe.

The behavior was reproduced with:

  • Forward-slash and backslash forms of C:\Program Files\Git\bin\bash.exe
  • C:\Program Files\Git\usr\bin\bash.exe
  • login omitted and login: false

As a control, an explicit PowerShell path in the same shell field works:

await tools.exec_command({
  cmd: "Write-Output SHELL_FIELD_POWERSHELL_OK",
  shell: "C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe",
  login: false
});

Output:

SHELL_FIELD_POWERSHELL_OK

This breaks repository instructions that require Git Bash syntax and explicitly direct the agent to pass Git Bash through exec_command.shell.

What steps can reproduce the bug?

  1. Install Codex Desktop and Git for Windows on native Windows.
  2. Confirm C:\Program Files\Git\bin\bash.exe exists and can run a .sh file directly.
  3. Ensure Git Bash's bin directory is not on the Codex process PATH, so where.exe bash returns no match. Git's normal C:\Program Files\Git\cmd directory may still be on PATH.
  4. Start a Codex Desktop thread in a Windows-native workspace.
  5. Ask the agent to execute the first tools.exec_command snippet above, with shell set to the absolute Git Bash path.
  6. Observe that Bash syntax is parsed by cmd.exe and fails.
  7. Optionally repeat with the PowerShell control. It succeeds, showing that the shell field is reaching shell selection but the Git Bash executable path is not being honored.

Reproduction rollout/session IDs:

  • 01a02368-7ce7-7e90-9487-6630fadf44ad (August 21 closest working baseline, embedded CLI 0.148.0-alpha.21)
  • 01a0128f-01c0-7380-90e5-bd5c2c65a168 (August 18 working subagent rollout; parent session 01a00eda-0b19-7f92-9ca4-5304a5210b08)
  • 01a031d0-e351-7241-80ab-cd8ba21c7709 (August 24 original failure; failing turn 01a031d0-ed00-7e41-81b5-e0927e37ab6d)
  • 01a031d4-7e07-7cf2-8e01-66b0cc07cbbf (August 24 controlled reproduction)

At evidence extraction in the controlled reproduction, the last-turn token usage was 114,174 tokens with a 258,400-token context window (about 44.2%). Reported primary and secondary rate-limit usage was 0%.

What is the expected behavior?

When exec_command.shell identifies an installed and supported shell, Codex should execute the command with that requested shell type.

For the reproduction above, expected output is similar to:

BASH=5.3.15(1)-release

If model-provided executable paths are intentionally not launched for security reasons, Codex should safely discover standard Git for Windows Bash installations or return a clear shell-resolution error. It should not silently fall back to a different shell whose syntax is incompatible with the command.

Additional information

The regression corresponds directly to commit 186b449 / PR #39607, “Resolve model-provided shells by type”. The observed behavioral boundary is embedded CLI 0.148.0-alpha.21 working on August 21 versus 0.149.0-alpha.4.1 failing on August 24; the App package number is not used to identify the responsible core behavior.

In the working 0.148.0-alpha.21 source:

In the failing 0.149.0-alpha.4.1 source:

PR #39607 explains that a model-provided path should select only the shell type and should not determine the executable Codex launches. That security goal is understandable, but on Windows it creates a regression when Git Bash exists at its standard absolute path while bare bash is not on PATH: Bash discovery fails and Codex silently switches to cmd.exe.

Possible fixes that preserve the security goal:

  1. Add safe Windows Bash discovery for standard Git for Windows locations such as C:\Program Files\Git\bin\bash.exe and C:\Program Files\Git\usr\bin\bash.exe.
  2. Return an explicit “requested Bash shell is unavailable” error instead of silently falling back to cmd.exe.
  3. If shell is intentionally only a shell-type hint, update the tool schema description; it currently describes the field as the shell binary to launch.

I searched existing issues before drafting this report. These are related but appear materially different:

  • #13199 broadly reports difficulty running Git Bash commands on Windows with CLI 0.106.0; it predates this regression and does not isolate an explicit absolute exec_command.shell path being discarded after PR Resolve model-provided shells by type #39607.
  • #16579 requests persistent configuration of the default Windows session shell.
  • #27474 concerns WSL runner startup and /bin/bash process creation.
  • #9581 concerns shell-aware command generation and cmd.exe wrapping, not an explicit absolute shell path being discarded.

A sanitized JSONL reproduction bundle is available as an attachment. It preserves the original rollout filenames and line numbers for the version metadata, the corroborating success, the failure, and the controlled reproduction without including the full conversations.

The standalone codex --version value is not used as the regression boundary here. Each rollout's own session_meta.cli_version identifies the CLI core actually embedded in Codex Desktop and responsible for that session.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appbugSomething isn't workingtool-callsIssues related to tool callingwindows-osIssues related to Codex on Windows systems

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions