TUI hangs indefinitely on Working with tui_app_server enabled, while --disable tui_app_server works normally on 0.149.0
What version of Codex CLI is running?
0.149.0
What subscription do you have?
Pro
Which model were you using?
gpt-5.6-sol
What platform is your computer?
Linux 5.4.0-81-generic x86_64 x86_64
What terminal emulator and version are you using (if applicable)?
VS Code Integrated Terminal 1.131.0 via Remote SSH on Linu
Codex doctor report
{
"schemaVersion": 1,
"generatedAt": "1787331198s since unix epoch",
"overallStatus": "warning",
"codexVersion": "0.149.0",
"checks": {
"app_server.status": {
"id": "app_server.status",
"category": "app-server",
"status": "ok",
"summary": "background server is running",
"details": {
"app-server version": "0.149.0",
"control socket": "/data/yezelin/.codex/app-server-control/app-server-control.sock",
"daemon state dir": "/data/yezelin/.codex/app-server-daemon",
"mode": "ephemeral",
"pid file": "/data/yezelin/.codex/app-server-daemon/app-server.pid (missing)",
"settings": "/data/yezelin/.codex/app-server-daemon/settings.json (missing)",
"status": "running",
"update-loop pid file": "/data/yezelin/.codex/app-server-daemon/app-server-updater.pid (missing)"
},
"remediation": null,
"durationMs": 266
},
"auth.credentials": {
"id": "auth.credentials",
"category": "auth",
"status": "ok",
"summary": "auth is configured",
"details": {
"auth file": "/data/yezelin/.codex/auth.json",
"auth storage mode": "File",
"stored API key": "false",
"stored ChatGPT tokens": "true",
"stored agent identity": "false",
"stored auth mode": "chatgpt"
},
"remediation": null,
"durationMs": 0
},
"config.load": {
"id": "config.load",
"category": "config",
"status": "ok",
"summary": "config loaded",
"details": {
"CODEX_HOME": "/data/yezelin/.codex",
"config.toml": "/data/yezelin/.codex/config.toml",
"config.toml parse": "ok",
"cwd": "/data/yezelin",
"enabled feature flags": "shell_tool, view_image, unified_exec, shell_snapshot, code_mode_host, terminal_resize_reflow, sqlite, memories, hooks, enable_request_compression, unbounded_connection_retries, multi_agent, tool_search_always_defer_mcp_tools, tool_suggest, plugins, in_app_browser, in_app_chat, in_app_dictation, in_app_updates, browser_use, browser_use_full_cdp_access, browser_use_external, computer_use, remote_plugin, plugin_sharing, image_generation, resize_all_images, item_ids, skill_mcp_dependency_install, skill_search, mentions_v2, steer, guardian_approval, goals, collaboration_modes, tool_call_mcp_elicitation, auth_elicitation, personality, fast_mode, tui_app_server, remote_compaction_v2, workspace_dependencies",
"feature flag overrides": "memories=true, apps=false",
"feature flags enabled": "42",
"log dir": "/data/yezelin/.codex/log",
"mcp servers": "0",
"model": "gpt-5.6-sol",
"model provider": "openai-resilient",
"sqlite home": "/data/yezelin/.codex"
},
"remediation": null,
"durationMs": 0
},
"git.environment": {
"id": "git.environment",
"category": "git",
"status": "ok",
"summary": "git version 2.25.1",
"details": {
"PATH git #1": "/usr/bin/git",
"PATH git #2": "/bin/git",
"PATH git entries": "2",
"git build options": "git version 2.25.1; cpu: x86_64; no commit associated with this build; sizeof-long: 8; sizeof-size_t: 8",
"git exec path": "/usr/lib/git-core",
"git version": "git version 2.25.1",
"repo detected": "false",
"selected git": "/usr/bin/git"
},
"remediation": null,
"durationMs": 60
},
"installation": {
"id": "installation",
"category": "install",
"status": "ok",
"summary": "installation looks consistent",
"details": {
"PATH codex #1": "/data//yezelin/.local/bin/codex",
"PATH codex #2": "/data/yezelin/.local/bin/codex",
"PATH codex #3": "/data/yezelin/.local/bin/codex",
"PATH codex #4": "/usr/bin/codex",
"PATH codex #5": "/bin/codex",
"PATH codex entries": "5",
"current executable": "/data/yezelin/.local/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex",
"install context": "npm (package /data/yezelin/.local/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl, bin /data/yezelin/.local/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin, resources /data/yezelin/.local/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex-resources, path /data/yezelin/.local/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex-path)",
"managed by bun": "false",
"managed by npm": "true",
"managed by pnpm": "false",
"managed package root": "/data/yezelin/.local/lib/node_modules/@openai/codex",
"npm update target": "/data/yezelin/.local/lib/node_modules/@openai/codex"
},
"remediation": null,
"durationMs": 83
},
"mcp.config": {
"id": "mcp.config",
"category": "mcp",
"status": "ok",
"summary": "no MCP servers configured",
"details": {},
"remediation": null,
"durationMs": 0
},
"network.env": {
"id": "network.env",
"category": "network",
"status": "ok",
"summary": "network-related environment looks readable",
"details": {
"managed proxy": "not configured",
"proxy env vars present": "http_proxy, https_proxy",
"respect system proxy": "disabled"
},
"remediation": null,
"durationMs": 0
},
"network.provider_reachability": {
"id": "network.provider_reachability",
"category": "reachability",
"status": "ok",
"summary": "active provider endpoints are reachable over HTTP",
"details": {
"ChatGPT inference URL": "https://chatgpt.com/backend-api/<redacted> reachable (HTTP 405)",
"reachability mode": "ChatGPT auth"
},
"remediation": null,
"durationMs": 785
},
"network.websocket_reachability": {
"id": "network.websocket_reachability",
"category": "websocket",
"status": "ok",
"summary": "Responses WebSocket is not enabled for the active provider",
"details": {
"model provider": "openai-resilient",
"provider name": "OpenAI",
"proxy env vars present": "http_proxy, https_proxy",
"supports websockets": "false",
"wire API": "responses"
},
"remediation": null,
"durationMs": 0
},
"runtime.provenance": {
"id": "runtime.provenance",
"category": "runtime",
"status": "ok",
"summary": "running npm on linux-x86_64",
"details": {
"commit": "unknown",
"current executable": "/data/yezelin/.local/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex",
"install method": "npm (package /data/yezelin/.local/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl, bin /data/yezelin/.local/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin, resources /data/yezelin/.local/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex-resources, path /data/yezelin/.local/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex-path)",
"platform": "linux-x86_64",
"version": "0.149.0"
},
"remediation": null,
"durationMs": 0
},
"runtime.search": {
"id": "runtime.search",
"category": "search",
"status": "ok",
"summary": "search is OK (bundled)",
"details": {
"search command": "/data/yezelin/.local/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex-path/rg",
"search command readiness": "file exists",
"search provider": "bundled"
},
"remediation": null,
"durationMs": 0
},
"sandbox.helpers": {
"id": "sandbox.helpers",
"category": "sandbox",
"status": "ok",
"summary": "sandbox configuration is readable",
"details": {
"approval policy": "OnRequest",
"codex-linux-sandbox helper": "/data/yezelin/.codex/tmp/arg0/codex-arg0URQtld/codex-linux-sandbox",
"execve wrapper helper": "/data/yezelin/.codex/tmp/arg0/codex-arg0URQtld/codex-execve-wrapper",
"filesystem sandbox": "restricted",
"network sandbox": "enabled"
},
"remediation": null,
"durationMs": 0
},
"security.endpoint": {
"id": "security.endpoint",
"category": "security",
"status": "ok",
"summary": "endpoint protection is not inspected on this platform",
"details": {
"endpoint products": "not inspected on this platform"
},
"remediation": null,
"durationMs": 0
},
"state.paths": {
"id": "state.paths",
"category": "state",
"status": "ok",
"summary": "state paths and databases are inspectable",
"details": {
"CODEX_HOME": "/data/yezelin/.codex (dir)",
"active rollout files": "200 files, 703998833 total bytes, 3519994 average bytes",
"archived rollout files": "3 files, 805003 total bytes, 268334 average bytes",
"goals DB": "/data/yezelin/.codex/goals_1.sqlite (file)",
"goals DB integrity": "ok",
"log DB": "/data/yezelin/.codex/logs_2.sqlite (file)",
"log DB integrity": "ok",
"log dir": "/data/yezelin/.codex/log (dir)",
"memories DB": "/data/yezelin/.codex/memories_1.sqlite (file)",
"memories DB integrity": "ok",
"queue DB": "/data/yezelin/.codex/queue_1.sqlite (file)",
"queue DB integrity": "ok",
"sqlite home": "/data/yezelin/.codex (dir)",
"state DB": "/data/yezelin/.codex/state_5.sqlite (file)",
"state DB integrity": "ok",
"thread history DB": "/data/yezelin/.codex/thread_history_1.sqlite (file)",
"thread history DB integrity": "ok"
},
"remediation": null,
"durationMs": 17905
},
"state.rollout_db_parity": {
"id": "state.rollout_db_parity",
"category": "threads",
"status": "warning",
"summary": "rollout files and state DB thread inventory differ",
"details": {
"default model provider": "openai-resilient",
"rollout DB active files": "200",
"rollout DB active rows": "188",
"rollout DB archive mismatches": "0",
"rollout DB archived files": "3",
"rollout DB archived rows": "3",
"rollout DB duplicate DB paths": "0",
"rollout DB duplicate rollout thread ids": "0",
"rollout DB malformed file names": "0",
"rollout DB missing active rows": "12",
"rollout DB missing active sample": [
"/data/yezelin/.codex/sessions/2026/03/22/rollout-2026-03-22T18-07-33-019d16bb-17f1-7f10-8da6-ee9a52e0224f.jsonl",
"/data/yezelin/.codex/sessions/2026/03/22/rollout-2026-03-22T18-27-00-019d16cc-e8ac-7a62-b72e-3034b6bf78dd.jsonl",
"/data/yezelin/.codex/sessions/2026/03/22/rollout-2026-03-22T18-00-11-019d16b4-59ba-7be2-afb0-5766af734fd7.jsonl",
"/data/yezelin/.codex/sessions/2026/03/22/rollout-2026-03-22T18-27-06-019d16cc-fcbe-7cf1-a394-eb00ab7c3de7.jsonl",
"/data/yezelin/.codex/sessions/2026/03/22/rollout-2026-03-22T18-00-11-019d16b4-598e-7ca2-a87c-1e91bbbfada7.jsonl"
],
"rollout DB missing archived rows": "0",
"rollout DB model providers": "openai=175, openai-resilient=12, litellm-deepseek-v4pro=2, vapi=2",
"rollout DB rows": "191",
"rollout DB scan cap reached": "false",
"rollout DB scan errors": "0",
"rollout DB sources": "cli=110, subagent:other=37, vscode=27, subagent:thread_spawn=11, exec=6",
"rollout DB stale rows": "0"
},
"issues": [
{
"severity": "warning",
"cause": "rollout files are missing from the state DB",
"measured": "12 active, 0 archived",
"expected": "every rollout file has a matching threads row",
"remedy": null,
"fields": []
}
],
"remediation": null,
"durationMs": 99
},
"system.disk": {
"id": "system.disk",
"category": "disk",
"status": "ok",
"summary": "sufficient free disk space (1326.1 GiB)",
"details": {
"CODEX_HOME available": "1326.1 GiB",
"failure threshold": "1.0 GiB",
"warning threshold": "5.0 GiB",
"worktree available": "1326.1 GiB"
},
"remediation": null,
"durationMs": 0
},
"system.environment": {
"id": "system.environment",
"category": "system",
"status": "ok",
"summary": "OS language en-US",
"details": {
"EDITOR": "not set",
"LANG": "en_US.UTF-8",
"VISUAL": "not set",
"os": "Ubuntu 20.4.0 (focal) [64-bit]",
"os language": "en-US",
"os type": "Ubuntu",
"os version": "20.4.0"
},
"remediation": null,
"durationMs": 58
},
"terminal.env": {
"id": "terminal.env",
"category": "terminal",
"status": "ok",
"summary": "terminal metadata was detected",
"details": {
"COLORTERM": "truecolor",
"SSH_CLIENT": "present",
"SSH_CONNECTION": "present",
"TERM_PROGRAM": "vscode",
"VSCODE_IPC_HOOK_CLI": "present",
"color output": "enabled",
"effective locale": "en_US.UTF-8",
"stderr is terminal": "true",
"stdin is terminal": "true",
"stdout is terminal": "true",
"terminal": "VS Code",
"terminal size": "177x30",
"terminal version": "1.131.0"
},
"remediation": null,
"durationMs": 0
},
"terminal.title": {
"id": "terminal.title",
"category": "title",
"status": "ok",
"summary": "terminal title default",
"details": {
"terminal title activity": "true",
"terminal title items": "activity, project-name",
"terminal title project source": "cwd",
"terminal title project value": "yezelin",
"terminal title source": "default"
},
"remediation": null,
"durationMs": 0
},
"updates.status": {
"id": "updates.status",
"category": "updates",
"status": "warning",
"summary": "update configuration is locally consistent",
"details": {
"cached latest version": "0.149.0",
"check for update on startup": "true",
"dismissed version": "0.144.5",
"last checked at": "2026-08-21T15:11:06.522875238Z",
"latest version probe": "curl: (28) Operation timed out after 5000 milliseconds with 283763 out of 290924 bytes received",
"npm update target": "/data/yezelin/.local/lib/node_modules/@openai/codex",
"update action": "npm install -g @openai/codex",
"version cache": "/data/yezelin/.codex/version.json"
},
"remediation": null,
"durationMs": 5092
}
}
}
What issue are you seeing?
On Codex CLI 0.149.0, the normal interactive TUI frequently hangs indefinitely at Working, even in a completely fresh session with a trivial prompt.
For example, starting:
codex
and sending:
Reply only OK
can leave the TUI at Working for many minutes. I have also observed a turn remain at Working for more than two hours without producing any output.
However, the same CLI and environment work normally when tui_app_server is disabled:
codex --disable tui_app_server -m gpt-5.6-sol
With this command, the same trivial prompt returns OK within a few seconds.
codex exec also completes successfully, although it sometimes emits model-manager timeout errors before the actual turn starts:
ERROR codex_models_manager::manager: failed to refresh available models: timeout waiting for child process to exit
For example:
time codex exec --skip-git-repo-check "Reply only OK"
completed successfully in approximately 33 seconds.
This strongly appears to be specific to the default TUI/app-server execution path rather than model inference itself.
What steps can reproduce the bug?
1.Install/run Codex CLI 0.149.0 on Linux x86_64.
2.Confirm the version:
codex --version
Output:
codex-cli 0.149.0
3.Start a completely fresh interactive session:
codex
4.Send a trivial prompt:
Reply only OK
5.Observe that the TUI remains at:
Working...
for minutes or indefinitely without producing a response.
6.Exit and repeat the same test with the app-server-backed TUI disabled:
codex --disable tui_app_server -m gpt-5.6-sol
7.Send the same trivial prompt.
Result: OK is returned within a few seconds.
I also tested with a fresh CODEX_HOME under /tmp to exclude existing sessions/state as the cause. The normal TUI still hangs:
CODEX_HOME=/tmp/codex-test-$USER codex
The underlying filesystem of the normal home directory is local ext4, not NFS/Ceph/Lustre.
While the normal TUI is hung, the native app-server and proxy processes remain alive with stable PIDs. Both binaries report:
codex-cli 0.149.0
All observed threads are in Sl state. The native app-server and proxy processes show approximately 0% CPU and are sleeping in:
futex_wait_queue_me
There is no observed crash/restart loop and no observed thread in D state.
What is the expected behavior?
A fresh interactive TUI session should process a trivial prompt normally and return a response within approximately the same time as the direct/non-app-server path.
In particular, the default:
codex
should not remain indefinitely at Working when:
codex --disable tui_app_server
can process the same prompt successfully within seconds.
If the app-server encounters an internal timeout or loses synchronization with the TUI, it should also surface an error or recover rather than leaving the turn permanently in the Working state.
Additional information
Workaround
The following consistently avoids the hang:
codex --disable tui_app_server -m gpt-5.6-sol
App-server versions
During earlier debugging, I discovered an old system-wide Codex 0.141.0 installation whose app-server processes were still running while my interactive CLI was newer.
Those stale processes were terminated.
I then reproduced the issue again after verifying that all relevant components were 0.149.0:
CLI: codex-cli 0.149.0
app-server: codex-cli 0.149.0
proxy: codex-cli 0.149.0
Therefore, the current reproduction is not caused by the earlier 0.141/0.149 version mismatch.
Process state while hung
The app-server and proxy PIDs remain stable rather than continuously restarting.
Example process state:
STAT %CPU WCHAN
Sl 0.0 futex_wait_queue_me
Sl 0.0 futex_wait_queue_me
All inspected threads were in Sl state.
Model manager observations
codex exec has emitted:
ERROR codex_models_manager::manager: failed to refresh available models: timeout waiting for child process to exit
twice during startup, but subsequently completed the request.
Model catalog timing:
$ time codex debug models >/tmp/codex-models-online.json
real 0m5.241s
$ time codex debug models --bundled >/tmp/codex-models-bundled.json
real 0m0.053s
I am not sure whether the model-manager timeout is directly responsible for the TUI/app-server hang, but it may be relevant.
Other controls
Fresh session reproduces the issue.
Fresh CODEX_HOME under /tmp also reproduces it.
Home filesystem is local ext4.
Codex state database was reported healthy by codex doctor.
Provider endpoints are reachable over HTTP.
codex exec can successfully invoke the model.
--disable tui_app_server consistently avoids the hang.
App-server and proxy are both confirmed to be 0.149.0.
4 Comments
Additional corroborating evidence from #39988: on macOS CLI 0.149.0, the same visible Working state can occur between completed tool calls after a promised next step, with no active tool call or new event; Esc stops only the stalled turn and preserves resumability, though the resumed session may stall again. This extends the symptom beyond the fresh-prompt/app-server reproduction.
Additional redacted diagnostic evidence: I reproduced the same silent-turn stall in the non-interactive
codex execpath on Codex CLI 0.147.0 (macOS arm64), so this is not limited to a visibly stuck TUI spinner.The ephemeral exec process completed several read-only commands, emitted a progress/analysis message promising the next edit, and then produced no tool call, final response, or error. After more than 55 minutes:
parse_wrapped_websocket_error_event, but that alone is not enough to infer a specific remote error;This looks consistent with an orphaned pending turn or missing completion/wakeup after a WebSocket/event-stream disruption, although the exact cause remains uncertain. The lack of an attributable persisted diagnostic for a still-live hung
codex execprocess is itself notable.I omitted the prompt, working directory, repository, usernames, host/network addresses, session identifiers, process identifiers, and raw stack trace. I can provide a further-sanitized symbolic stack excerpt if that would help.
Rollout JSONL plus the indexed diagnostic log sharpen this reproduction and its relationship to #32659.
The failed interactive turn does not have #32659's exact partial-tool signature:
completed;status=in_progressor empty input;response.output_text.done,response.content_part.done, and output-item completion for that message;A minimal resumed turn then recorded task start and the user message, but no assistant reasoning, message, or tool item at all for 4m27s before manual abort.
For comparison, a successful run on the same host, CLI version, repository state, and terminal manager recorded all tool calls completed; its final assistant message was followed immediately by the terminal WebSocket timing/lifecycle record and
task_complete.This therefore looks close to #32659's broader stream-liveness family, but at a later truncation boundary: assistant output is fully emitted, while the terminal response/turn completion event never arrives. It is not evidence of an in-progress custom tool call with missing input.
No raw rollout/log content is attached because it contains identifying working context. This summary omits prompts, paths, repository/user/host/network identifiers, item/session/turn IDs, and command contents.
Additional aggregate evidence from local rollout JSONL and the indexed Codex diagnostic log strengthens the relationship to #32659. Raw logs are not attached.
Across one bounded three-day corpus:
gpt-5.6-lunaat high or xhigh reasoning through the TUI/app-server path.custom_tool_callrecord immediately after the final completed rollout item. The unmatched record has no correspondingoutput_item_done, no completed rollout tool item, and no dispatched tool. The other two cases have no boundary tool diagnostic and are inconclusive rather than contradictory.This explains why rollout JSONL alone initially looked like a completed reasoning/message item followed by silence: the following custom-tool item never completed and therefore never appeared as a completed rollout response item. The indexed diagnostic log exposes the partial start.
This summary intentionally omits exact timestamps, prompts, commands, paths, repositories, user/host/network identifiers, session/turn/item/call/response IDs, and raw log bodies.