openai / openai/codex

Codex Desktop (Windows): code-mode host exits during handshake, breaking every tool call for code_mode_only models

Open
#41,507 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app app-server bug sandbox windows-os
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

Summary

On Codex Desktop for Windows, every tool call fails with:

dispatch_tool_call_with_terminal_outcome: error=code-mode host exited during handshake

Because gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna and gpt-reserve are tool_mode = code_mode_only, this makes the whole 5.6 model family unusable in the desktop app — the agent cannot run a single command, read a file, or use any skill/plugin.

The same codex.exe binary works correctly when run as a CLI. The failure is specific to the desktop app's app-server, and it reproduces with a completely empty CODEX_HOME, so it is not caused by user configuration.

Environment

OS Windows 11 26100/26200 (10.0.26200), x64, zh-CN locale
Codex Desktop package 26.825.4187.0, internal version 26.825.32147
codex-cli 0.150.0-alpha.12.2
Auth ChatGPT (Plus)
Models affected gpt-5.6-terra, gpt-5.6-luna (tool_mode = code_mode_only)
Models unaffected gpt-5.5, gpt-5.4 (tool_mode = None)

Reproduction

  1. Open Codex Desktop, select gpt-5.6-terra.
  2. Ask it to run any command, e.g. execute echo hello.
  3. The tool call fails; logs_2.sqlite records code-mode host exited during handshake.

Observed 100% of the time, across dozens of attempts over three days.

Key evidence: reproduces with an empty CODEX_HOME

Set CODEX_HOME to a fresh directory containing only auth.json, restart the desktop app, and retry. Same failure. From that clean home's logs_2.sqlite:

16:48:38  (CLI)      exec_command failed ... CreateProcess { message: "Rejected(...)" }
17:22:22  (Desktop)  dispatch_tool_call_with_terminal_outcome: error=code-mode host exited during handshake

No config, no MCP servers, no plugins, no history — the desktop app still fails, while the CLI against the same home gets past the handshake and executes the command.

Also ruled out by direct testing: disabling all 4 MCP servers, disabling all 13 plugins, resetting cap_sid, and clearing accumulated sandbox ACEs. None changed the desktop behaviour.

What the host process actually does

Captured via WMI process polling (40 ms) while reproducing:

START pid=11856 ppid=20120(codex) codex-code-mode-host.exe
      "C:\Users\<user>\AppData\Local\OpenAI\Codex\bin\<hash>\codex-code-mode-host.exe"
EXIT  pid=11856                     (~190 ms later)

The process is spawned (so this is not AV blocking process creation) with no arguments, and dies shortly after.

Driving codex-code-mode-host.exe --listen stdio manually shows exactly two ways it can exit that early:

stdin condition result
pipe, no data written stays alive indefinitely
stdin closed immediately (EOF) exit 0 after ~20 ms
non-code-mode bytes (e.g. a JSON-RPC frame) exit 1 after ~20 ms, Error: failed to read code-mode client hello

So the host is healthy; it is the app-server that fails to deliver a valid client hello over the stdio transport.

For reference, the IPC framing is a little-endian u32 length prefix followed by JSON requiring a type field, with a 64 MiB frame cap. Feeding it a JSON-RPC message produces:

Error: failed to read code-mode client hello
Caused by:
    code-mode IPC frame length 1936335483 exceeds 67108864 bytes

(1936335483 = 0x736A227B = the first four bytes of {"jsonrpc" read as LE u32.) That is consistent with the host receiving something other than a code-mode hello on stdin — possibly the app-server's own JSON-RPC channel — but I could not confirm the actual bytes the app-server writes.

The host binary itself is fine: SHA-256 matches the copy shipped in the MSIX package, Authenticode signature is valid (OpenAI OpCo, LLC), and it starts correctly standalone in stdio mode, in grpc:// mode, and when launched inside codex sandbox.

Things that are NOT the cause (verified)

  • Endpoint protection (ESET Internet Security 19.2.7.0) — no detections, and the host process is created successfully
  • Corrupted or tampered binaries — hashes and signatures verified
  • node_repl MCP server / bundled Node kernel — MCP handshake and js tool calls work
  • Bundled Python runtime (3.12.13) and Node (v24.19.0) — both execute fine
  • Missing document/pdf/spreadsheet plugins — present on disk
  • Model API connectivity — codex doctor reports WebSocket 101 and auth OK
  • Any user configuration — reproduces with an empty CODEX_HOME

Secondary bug: Windows sandbox cannot create a token (error 1344)

Separate from the above, and visible on the CLI path:

exec_command failed for `pwsh.exe -Command 'echo hello'`:
  CreateProcess { message: "Rejected(\"Failed to create unified exec process:
                            SetTokenInformation(TokenDefaultDacl) failed: 1344\")" }

1344 is ERROR_NO_MORE_MEMORY_FOR_SECURITY_INFO — the security descriptor being applied is too large.

This appears to be driven by two unbounded caches:

  1. $CODEX_HOME/cap_sid grows one capability SID per writable root path, forever. On this machine it had reached 143 SIDs / 12,485 bytes, because a session had once used the user's home directory as its workspace — Codex minted a separate SID for each of the 141 entries under it.

  2. The matching capability deny ACEs written onto world-writable directories are never removed. C:\Users\Public had accumulated 288 ACEs (10,264-byte security descriptor) and C:\QLDownload 285, versus ~4 on a normal directory. 139 orphaned SIDs on each — one per sandbox session.

The CLI degrades gracefully here (with approval_policy = OnRequest it falls back to asking the user to approve running outside the sandbox), so it stays usable. The desktop app runs with approval_policy = Never and sandbox_policy = DangerFullAccess, so there is no fallback path.

Note that clearing both caches did not fix the handshake failure — they are independent issues.

Impact

The 5.6 model family is entirely unusable in Codex Desktop on this machine. Current workarounds:

  • Use the CLI for 5.6 models (approve each command when the sandbox fails)
  • Use gpt-5.5 / gpt-5.4 in the desktop app (tool_mode = None, so they bypass code mode)

A smaller, separate observation

When the code-mode tool call fails, the model frequently presents the expected output as if the command had run — e.g. answering with a hello code block after custom_tool_call_output was code-mode host exited during handshake. From the rollout JSONL:

{"type":"custom_tool_call_output","output":"code-mode host exited during handshake"}
{"type":"message","role":"assistant","content":[{"type":"output_text","text":"`hello`"}],"phase":"final_answer"}

This made the failure look intermittent for a long time and cost real debugging effort. It might be worth surfacing tool-call failures more explicitly to the model, or to the user in the transcript.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the Desktop app-server's stdio launch path for codex-code-mode-host.exe and compare it with the working CLI path. Use logs_2.sqlite, an empty CODEX_HOME, and the documented standalone host behavior to identify what reaches the handshake. Done means affected code-mode-only models complete a tool call in Desktop; treat the Windows token/ACE accumulation and transcript behavior as separate findings.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli, desktop-dev, operating-systems
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.