Repository navigation
Windows: model picker stays stale after ocx sync --restart-codex until full desktop app restart #2292
Description
Summary
On Windows, ocx sync --restart-codex rewrites the Codex model catalog and restarts the Codex app-server (codex.exe app-server), but the desktop app's model picker keeps showing the stale list. Only a full quit and relaunch of the desktop app refreshes it. On macOS the same command updates the picker immediately.
The desktop UI (Electron, process name ChatGPT.exe) fetches model/list / config/read from its child app-server over stdio and caches them; it invalidates that cache on a codex-app-server-initialized event. Killing only the app-server child externally does not reliably produce that event on Windows, so the picker stays stale even though the fresh app-server has the new catalog in memory.
Reproduction
- Run
ocx sync --restart-codexwhile the Codex desktop app is open. - Observe the output: catalog rewritten, app-server PIDs stopped and respawned.
- Check the process table:
codex.exehas a fresh start time (e.g. synced 20:57, new PID 8592 started 20:59) while allChatGPT.exeUI processes keep their earlier start time. - Open the model picker: it still lists only the old models instead of the 5 newly appended ones.
- Fully quit the desktop app and relaunch: the picker now shows the new models.
Expected: after ocx sync --restart-codex, the picker reflects the new catalog without a full app restart (as on macOS), or at minimum there is a supported way to force the refresh.
Version
2.27.0
Operating system
Windows 11 Pro (build 26200)
Logs or error output
[opencodex] Removed unsupported reasoning efforts: max, ultra
+ 5 models appended to Codex catalog (C:\Users\super\.codex\opencodex-catalog.json)
Stopping Codex app-server process(es): 15060, 5092 ...
Stopped Codex app-server PID(s): 5092, 15060
# picker still stale until full app restartRelated upstream issues (unverified status)
- Codex Desktop model picker filters out models returned from model_catalog_json openai/codex#19694 - desktop model picker filters out models returned from model_catalog_json
- Codex Desktop ignores project-local model_catalog_json for fresh project threads openai/codex#26308 - desktop ignores project-local model_catalog_json for fresh threads
- Custom model metadata cannot be resolved although model_catalog_json is successfully loaded 已成功加载 model_catalog_json,但仍无法解析自定义模型元数据 openai/codex#32349 - custom model metadata is not resolved
- Desktop: model_catalog_json loaded but custom models not shown in picker (regression, related to #32349) openai/codex#34487 - desktop model picker is empty with custom providers
Note: the app is currently distributed as a beta-channel MSIX package (OpenAI.Codex 26.818.3698.0); this behavior was observed on that build and may change as the app matures.
Proposed direction
A --restart-desktop-app style option for ocx sync on Windows that gracefully closes the Electron shell (CloseMainWindow), falls back to taskkill /PID <root> /T /F bounded to the package install location, and relaunches via the AUMID (shell:AppsFolder\OpenAI.Codex_...!App). A working standalone implementation exists in scripts/restart-codex-desktop-app.ps1 (commit 58abd7b6d).
Activity
lidge-jun commentedon Aug 21, 2026
리뷰 · 우선순위 72 / 80
지금
devHEAD236e03342에서 이 재현이 코드랑 맞음.src/cli/dispatch.ts:205-231ocx sync가--restart-codex면 카탈로그 쓴 다음afterCatalogWriteHandleAppServers({ restart: true })만 탐. 그 함수는src/codex/app-server-processes.ts:1071-1101. 매칭은isCodexAppServerCommandLine(:247-274).codex/codex.exe/codex.cmd/타깃트리플 + 서브커맨드app-server, 아니면codex-code-mode-host.ChatGPT.exe는 토큰이 아님. 테스트가hermes-codex-bridge-mcp/opencodex app-server를 false로 잠금 (tests/codex-app-server-processes.test.ts:433-437). Electron 셸을 고의로 안 죽임. 리포터가 본 거랑 같음.codex.exePID는 갈아탔고ChatGPT.exe시작 시각은 그대로.sync-cache도 같은 구멍 (dispatch.ts:261-272).Windows 종료가
/T라서 부모까지 가는 줄 알 수 있음. 아님.defaultKillCodexAppServer(:976-998)가taskkill /PID <app-server> /T /F./T는 그 PID의 자식임. Electron 셸은 부모. 주석이 그거임 (:958-966). 테스트가/PID 4242 /T /F만 잠그고 시그널 폴스루 없음 (:980-997). Unix SIGTERM은 그레이스풀이라 대칭으로 SIGKILL 올리지 말라는 주석 (:968-970). 그 비대칭 유지해야 함.--restart-codex를ChatGPT.exe로 넓히면 #476 내로우 매칭이 죽음. 레지스트리도 "SIGTERM only to matching app-server / code-mode-host" (src/cli/registry.ts:94). 광고 그대로임. 거짓말은 아님. 범위가 픽커를 커버 못 함.더 큼. 재시작이 "성공"한 뒤 진단이 OK를 찍음.
collectCodexAppServerCatalogState(:774-824)는 앱-서버 시작 시각 vs 카탈로그 mtime. 새codex.exe가 카탈로그 다음에 뜨면fresh.ocx doctor:1061-1066이[OK] Codex app-server model catalog is current with the on-disk catalog.픽커는 Electron이model/list/config/read를 stdio로 받아서codex-app-server-initialized에만 무효화함. 외부 taskkill은 Windows MSIX 베타에서 그 이벤트를 안 냄. 닥터가 OK, 픽커는 옛 목록. 힌트도 같은 곳을 가리킴.STALE_CODEX_APP_SERVER_HINT(:19-20)랑formatStaleCodexAppServerWarning(:500-508)랑 닥터:1062가 전부ocx sync --restart-codex. 그 플래그를 이미 썼음. GUI/api/system/codex-restart(src/codex/app-server-restart-service.ts,src/lib/codex-restart-contract.ts)도 같은restartCodexAppServers임. 대시보드 클릭도 같은 구멍.#2291이랑 다른 층임. 그건 0바이트 쓰기 코디네이터가 주입을 거절함. 이건 카탈로그 기록 + 앱-서버 리스폰 다음 Electron 캐시. 로그의
+ 5 models appended가 그 증거임. 중복 아님. 닫지 말 것. 본문 업스트림 openai/codex#19694/#26308/#32349/#34487는 픽커 필터/프로젝트 로컬 카탈로그 쪽임. 검증 안 함. 이 이슈의 계약은 ocx가 Windows에서 셸 캐시를 깨거나, 못 깨면 거짓 OK를 안 찍는 거임. 보고 버전 2.27.0. 현재 런타임 카탈로그는d23c3179fOx Alpha + DeepSeek vision. 그 5개가 픽커에 안 보이는 바로 그 경로임.제안
--restart-desktop-app이 맞음. 기본값으로--restart-codex에 넣지 말 것. 앱-서버 킬은 턴 중단 동의. 데스크톱 킬은 창·컴포저·스레드까지. 다른 동의임. 본문이 가리킨scripts/restart-codex-desktop-app.ps1(커밋58abd7b6d)은 현재dev에 없음.scripts/에 ps1 없음. 단독 스크립트로 두지 말고 기존resolveTrustedWindowsPowerShellExe/resolveTrustedWindowsTaskkillExe심에 태움. CloseMainWindow 먼저. 타임아웃 후 taskkill은 패키지 설치 경로(WindowsApps\OpenAI.Codex_*또는 AUMID로 확인한 루트)에 바운드. 임의ChatGPT.exe금지. 재실행은shell:AppsFolder\<AUMID>!App. AUMID는 베타 MSIX가 빌드마다 바뀜 (OpenAI.Codex 26.818.3698.0). 하드코드 금지. 발견 실패면 죽이지 말고 수동 종료를 찍음. Unix/macOS 경로는 손대지 말 것. 거긴 이미 됨.#2188 L1–L9 사이드카 이미
dev.x_search넣지 말 것. Grok OAuth Chat 기본(#2255)/GUI 옵트인 Responses(#2266)/#2283 웹서치 필드랑 다른 레인임.types.ts/config.ts스플릿 안 씹힘. 스키마 PR 아님. 리베이스하지 말고 닫으라는 케이스 아님. 프리뷰 배포 아님. v2.29.0 이미 태그됨. 헤드236e03342는 #2290 릴리스 deploy-key 푸시. 핫 크래시는 아닌데 광고 플래그가 Windows에서 픽커를 안 고치고 닥터가 OK. 그래서 72.해결방안:
--restart-codex매칭은 앱-서버만 유지. Windows 전용--restart-desktop-app을 옵트인으로 추가. CloseMainWindow → 패키지 바운드 taskkill → AUMID 재실행. AUMID/설치 경로 발견 실패면 신호하지 말고 "데스크톱 앱을 완전히 종료했다가 다시 켜라"를 찍음.ocx doctor는 앱-서버가fresh여도 Windows에서ChatGPT.exe가 카탈로그보다 오래됐으면 OK를 찍지 말 것. 힌트/STALE_CODEX_APP_SERVER_HINT는--restart-codex만 가리키지 말 것. 회귀는 (1)ChatGPT.exe는isCodexAppServerCommandLinefalse (2)--restart-codex는 앱-서버만 taskkill (3) 데스크톱 옵션은 패키지 밖 PID를 안 죽임 (4) Unix SIGTERM 비대칭 유지. 스플릿이app-server-processes.ts를 옮기면 리베이스하지 말고 닫고 다시 짜라. 지금은 그 정도 아님.이 댓글은 grok-bot이 작성했습니다
Ingwannu commentedon Aug 21, 2026
Confirmed against current
dev@236e03342.The current sync path parses only
--restart-codex. After a real catalog/cache write it callsafterCatalogWriteHandleAppServers(), whose matcher intentionally targets onlycodex ... app-serverandcodex-code-mode-host. It never closes or relaunches the WindowsChatGPT.exedesktop shell. Therefore replacing the child app-server can leave the renderer cache alive exactly as reported.I will keep the fix explicit and Windows-only:
--restart-desktop-appflag; it will never be the default and will not be implied by--restart-codex;ChatGPT.exeprocess;I will open a Draft PR against
devand leave it unmerged for independent Windows/maintainer review. The standalone58abd7b6dobject named in the report is not reachable from this repository clone, so I will validate the behavior from the current source contract rather than importing an unavailable patch.Ingwannu commentedon Aug 21, 2026
Status after #2293 merged into
devasc0cbe494e: the repository now contains the standalone PowerShell helper, but this issue is not resolved yet.The merged helper is under
scripts/, which is not part of the normal npm package payload, andocx syncstill has no packaged--restart-desktop-appoption. The existing--restart-codexpath still restarts only the app-server child, and doctor can still report that child as fresh while the Desktop shell retains the old picker cache.The remaining completion boundary is therefore the explicit Windows-only CLI integration described above: packaged delivery, trusted package/AUMID discovery, identity-bounded graceful/forced shutdown, proof that every original verified target exited before relaunch, no action on discovery ambiguity, focused Windows regressions, and an external-terminal mutating smoke test. Keeping #2292 open as the tracking issue.
devlog: backlog disposition program roadmap (work-phase 0, docs-only)
feat(cli): add an opt-in Windows desktop-app restart for a stale mode…
Merge pull request #2384 from lidge-jun/codex/wp4-record
devlog: work-phase 4 record — lidge-jun#2292, and the audit that arri…
feat(cli): add an opt-in Windows desktop-app restart for a stale mode…
lidge-jun commentedon Aug 23, 2026
Fixed by #2382, merged as 84ee2e2 (
a3bbcdb03 feat(cli): add an opt-in Windows desktop-app restart for a stale model picker). Verified present inorigin/devhistory.The restart is opt-in on purpose. The desktop UI caches
model/listand invalidates only oncodex-app-server-initialized, so restarting the app-server child alone cannot refresh the picker — only a full app restart does. Making that automatic would tear down a user's UI without asking, so it stays behind an explicit flag.twk0672005 commentedon Aug 23, 2026
Pre-fix validation only: this was observed on npm release
2.31.0, which predates the fix merged in #2382. I have not yet validated the currentdevimplementation.Additional real-machine evidence from Windows 11 build
10.0.26200, using npm release2.31.0before OpenCodex was uninstalled from this machine:10100/OpenCodex routing.Reconnecting... waiting for network/error sending request.codex.exe ... app-serverprocess had been alive for roughly two days, predating the config restore and CLI/cache alignment. It retained many old TCP connections, including numerousCLOSE_WAITentries.OpenAI.CodexWindows app process tree and relaunching through the discovered AppsFolder identity created a fresh app-server with:10100;CLOSE_WAITconnections;ready: true.This matches the issue's distinction between restarting the app-server child and restarting the Windows Desktop shell. It also validates why an explicit, package-identity-bound desktop restart is necessary: disk config and CLI health alone are not sufficient evidence that the existing Desktop renderer/session has reloaded the new runtime state.
This supports the original failure mode; it is not post-merge validation of #2382.
All paths, account identifiers, tokens, and private session details have been removed.
Merge from upstream (#8)
devlog: backlog disposition program roadmap (work-phase 0, docs-only)
feat(cli): add an opt-in Windows desktop-app restart for a stale mode…
devlog: work-phase 4 record — lidge-jun#2292, and the audit that arri…
Merge pull request lidge-jun#2384 from lidge-jun/codex/wp4-record