Skip to content

Windows: model picker stays stale after ocx sync --restart-codex until full desktop app restart #2292

Closed

Description

@lidge-jun

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

  1. Run ocx sync --restart-codex while the Codex desktop app is open.
  2. Observe the output: catalog rewritten, app-server PIDs stopped and respawned.
  3. Check the process table: codex.exe has a fresh start time (e.g. synced 20:57, new PID 8592 started 20:59) while all ChatGPT.exe UI processes keep their earlier start time.
  4. Open the model picker: it still lists only the old models instead of the 5 newly appended ones.
  5. 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 restart

Related upstream issues (unverified status)

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

  1. added
    catalogModel catalog, slugs, visibility, routed entries
    cliCLI, config inject, packaging flags
    platformOS/service/tray/ACL (Windows-heavy, not Windows-only)
    on Aug 21, 2026
  2. lidge-jun commented on Aug 21, 2026

    @lidge-jun
    OwnerAuthor

    리뷰 · 우선순위 72 / 80

    지금 dev HEAD 236e03342에서 이 재현이 코드랑 맞음. src/cli/dispatch.ts:205-231 ocx 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.exe PID는 갈아탔고 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. 현재 런타임 카탈로그는 d23c3179f Ox 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는 isCodexAppServerCommandLine false (2) --restart-codex는 앱-서버만 taskkill (3) 데스크톱 옵션은 패키지 밖 PID를 안 죽임 (4) Unix SIGTERM 비대칭 유지. 스플릿이 app-server-processes.ts를 옮기면 리베이스하지 말고 닫고 다시 짜라. 지금은 그 정도 아님.

    이 댓글은 grok-bot이 작성했습니다

  3. Ingwannu commented on Aug 21, 2026

    @Ingwannu
    Owner

    Confirmed against current dev@236e03342.

    The current sync path parses only --restart-codex. After a real catalog/cache write it calls afterCatalogWriteHandleAppServers(), whose matcher intentionally targets only codex ... app-server and codex-code-mode-host. It never closes or relaunches the Windows ChatGPT.exe desktop 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:

    • add an opt-in --restart-desktop-app flag; it will never be the default and will not be implied by --restart-codex;
    • run it only after an actual catalog/cache write;
    • discover the current-user OpenAI Codex/Codex Beta package and AUMID, then bind process selection to that package identity rather than matching every ChatGPT.exe process;
    • request a graceful close first, use a bounded wait, and allow forced tree termination only for the still-identical verified desktop process tree;
    • relaunch through the discovered AppsFolder identity and fail closed with an actionable message if package/process identity cannot be proven;
    • preserve the existing app-server-only behavior and macOS/Linux paths;
    • add argument-wiring, no-write, identity, timeout, and relaunch regressions plus CLI documentation.

    I will open a Draft PR against dev and leave it unmerged for independent Windows/maintainer review. The standalone 58abd7b6d object 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.

  4. Ingwannu commented on Aug 21, 2026

    @Ingwannu
    Owner

    Status after #2293 merged into dev as c0cbe494e: 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, and ocx sync still has no packaged --restart-desktop-app option. The existing --restart-codex path 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.

  5. added a commit that references this issue on Aug 22, 2026
  6. added a commit that references this issue on Aug 22, 2026
  7. lidge-jun commented on Aug 23, 2026

    @lidge-jun
    OwnerAuthor

    Fixed by #2382, merged as 84ee2e2 (a3bbcdb03 feat(cli): add an opt-in Windows desktop-app restart for a stale model picker). Verified present in origin/dev history.

    The restart is opt-in on purpose. The desktop UI caches model/list and invalidates only on codex-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.

  8. twk0672005 commented on Aug 23, 2026

    @twk0672005

    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 current dev implementation.

    Additional real-machine evidence from Windows 11 build 10.0.26200, using npm release 2.31.0 before OpenCodex was uninstalled from this machine:

    • The on-disk Codex config had already been restored to the native OpenAI route and contained no localhost 10100/OpenCodex routing.
    • CLI/native requests were healthy, but the existing Codex Desktop window still showed Reconnecting... waiting for network / error sending request.
    • The Desktop codex.exe ... app-server process had been alive for roughly two days, predating the config restore and CLI/cache alignment. It retained many old TCP connections, including numerous CLOSE_WAIT entries.
    • Restarting only CLI-side components did not repair the visible Desktop session.
    • Fully closing the package-bound OpenAI.Codex Windows app process tree and relaunching through the discovered AppsFolder identity created a fresh app-server with:
      • zero connections to port 10100;
      • five established HTTPS connections;
      • zero CLOSE_WAIT connections;
      • verified ChatGPT authentication and ready: true.
    • The user then confirmed that the new Desktop window could send and receive messages normally.

    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.

  9. added a commit that references this issue on Aug 26, 2026
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

    bugSomething isn't workingcatalogModel catalog, slugs, visibility, routed entriescliCLI, config inject, packaging flagsplatformOS/service/tray/ACL (Windows-heavy, not Windows-only)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions