Repository navigation
Windows (zh-CN): ocx sync always refuses — localized schtasks output breaks the task-absence probe, and the 2s full-listing fallback times out #2914
Description
Activity
- addedbugSomething isn't workingSomething isn't workingcliCLI, config inject, packaging flagsCLI, config inject, packaging flagsplatformOS/service/tray/ACL (Windows-heavy, not Windows-only)OS/service/tray/ACL (Windows-heavy, not Windows-only)serviceService lifecycle (WinSW/launchd/scheduler)Service lifecycle (WinSW/launchd/scheduler)
on Aug 29, 2026 리뷰 · 우선순위 72 / 80
이 이슈는 중국어 Windows 에서
ocx sync가 항상 거절되는 실사용 버그다. 지금devHEAD 는a0a8e8e2b(#2912) 이다. Windows 쪽은#2857이 스케줄러 홈 범위를 고쳤고,#1573과#1933이decodeWindowsTextBytes로 schtasks/레지스트리 바이트를 읽게 했다. 그 디코더는 한국어(ko→ euc-kr)와 서유럽 1252만 안다. 중국어 호스트는 그 테이블 밖이다. 작업이 없고 서비스도 없으면 소유 답은 "없음" 이어야 한다. 없으면 이 홈이 설정 파일을 써도 된다. 프로브가 없음을 증명 못 하면unknown이 되고, 소유를 못 밝혔다고 sync 가 거절한다.첫 구멍은 파일 없음 검사가 영어만 본다는 점이다.
src/service-manager-probe.ts539행SCHTASKS_TASK_NOT_FOUND_EN은cannot find the file specified만 본다. zh-CN 에서schtasks /query /tn opencodex-proxy /xml은 종료 코드 1과 GBK 바이트를 낸다. 글자는错误: 系统找不到指定的文件。이다.src/lib/windows-text.ts57행legacyEncodingForLocale은ko와 windows-1252 언어만 돌려준다.zh는 null 이라 UTF-8 폴백이 되고 글자가 깨진다. 깨진 글자에는 영어 문장이 없으니 정규식이 절대 안 맞는다.두 번째 구멍은 그 다음 폴백이다. 영어가 아니면
schtasks /query /fo CSV /nh전체 목록을 2초 안에 읽는다.SERVICE_PROBE_TIMEOUT_MS는 33행에 2000이다. 주석도 "느린 답은 없는 답과 같다"고 적혀 있다. 제보 호스트는 작업 401개에 12.3초가 걸린다. 2초에 끊기면timedOut이고registered: unknown이다. 쓰기가 거절된다.그 다음 단계가 또 있다.
src/codex/user-identity.ts40행 데스크톱 PowerShell 조회 한도는 8초다. CI만 54행에서 30초다. 주석은 8초가 진짜 데스크톱에 넉넉하다고 적는다. 제보 호스트는 powershell 빈 실행만 약 3초, SID 3.2초, LocalAppData 4.6초다. 첫 프로브를 고쳐도 여기서 가끔 또 거절된다.types.ts/config.ts 분할과 무관하다. 독립 버그픽스다. close-don't-rebase 대상이 아니다. 제보자가 로컬에서 디코드/문장/한도 셋을 고치면 프로브가
unknown → absent가 되고, 입장이refused → admitted가 되고,ocx sync가 0으로 끝났다.경로 src/lib/windows-text.ts 57행 -
zh와ja가 없다. 같은 파일 51-55행은 CP932 바이트를 1252로 읽으면 경로가 조작된다고 경고한다.ja를 넣을 때는shift_jis를 그 로케일에만 묶어야 한다.zh-Hant는 gbk 가 아니라 big5 쪽이 맞을 수 있다.라인 src/service-manager-probe.ts 539 - 영어 한 줄만 absent 확정이다. 디코드가 되면 중국어/일본어 문장을 넣거나, 디코드 성공 뒤에 로케일 중립 신호를 써야 한다. 종료 코드 1만으로 없음이라고 단정하면 다른 실패와 섞인다.
라인 src/service-manager-probe.ts 33, 577 - 2초 전체 목록은 작업이 많은 호스트에서 항상 진다. 한도를 올리는 건 입장(admission)을 늦춘다. 이름 조회가 로케일을 이기면 이 목록은 안 타도 된다.
라인 src/codex/user-identity.ts 40 vs 54 - 8초는 "진짜 데스크톱은 빠르다"는 가정이다. 제보 기계는 그 가정이 아니다. 한도를 올리면 멈춘 자식이 더 오래 버틴다. 프로세스 안 메모가 있으면 입장 단계가 스폰 비용을 반복해 안 내도 된다.
메인테이너의 판단이 필요한 지점
- 1차 고침을 디코드 + 파일없음 문장으로 할지, schtasks 종료 코드만으로 할지
zh-Hans는 gbk 인지 gb18030 인지,zh-Hant는 big5 인지ja→ shift_jis 를 파일의 CP932 경고와 어떻게 맞출지- identity 8초를 같이 올릴지, 메모만 따로 할지. 제보자는 로컬에서 셋 다 고쳐서 sync 가 통과했다
너의 추천
독립 버그픽스로 받아라. 전체 목록 2초를 올리는 건 나중이고, 먼저legacyEncodingForLocale에 zh(및 필요하면 ja)를 넣고 파일없음 검사를 디코드된 문장으로 통과시켜라. 그러면 작업이 없는 호스트는 12초 목록을 안 탄다. identity 타임아웃은 별 커밋으로 메모 또는 한도를 검토해라. 제보자 로컬 패치가 이미 그 순서로 동작했다.이 댓글은 grok-bot이 작성했습니다
- added a commit that references this issue
on Aug 29, 2026 Fixed on
devin the merge below (#2918).Your diagnosis was right on all three points, and the measurements are what made it actionable — the 401-task/12.3 s figure is the reason the second gap is a real defect rather than a theoretical one.
What shipped:
zh→gbk,zh-Hant/zh-TW/zh-HK/zh-MO→big5,ja→shift_jis, and the full listing gets its own 20 s budget through a per-call override while the targeted queries keep the 2 s admission ceiling. I checked eachTextDecoderexists and rejects mismatched bytes fatally before relying on it, and the test fixtures are real generated bytes rather than hand-typed hex — my first hand-written attempt was wrong and the test caught it.One suggestion I tried and rejected. Rather than add localized substrings, I attempted the general version: query a task name nothing can own, and treat whatever comes back as that host's not-found signature. It is unsafe.
schtasksexits 1 for both "task not found" and "access denied", so on a locked-down host the control and real queries return the same message, the signatures match, and the probe reportsabsent— a false clean machine, in the one direction that lets a write proceed into a home another process owns. The repository's existing access-denied test went red immediately. The reasoning is now in the source comment so it does not get rebuilt later. That leaves the listing as the only locale-neutral evidence, which is exactly why its budget was the fix.Deliberately not included: the
WINDOWS_POWERSHELL_LOOKUP_TIMEOUT_MS = 8000ceiling. Your measurements make a good case that it is marginal on a contended desktop, but it is a different subsystem with a different failure mode, and the better fix is plausibly reusing the per-process memo rather than a larger number. It should not ride along inside a probe fix — please open a separate issue if you would like it tracked, or say so here and I will.I could not reproduce your host: I am on macOS with no zh-CN Windows machine, so the byte handling and the timeout arithmetic are verified here, and the end-to-end
ocx syncrecovery rests on your report.- added 3 commits that reference this issue
on Aug 29, 2026 - added 4 commits that reference this issue
on Sep 14, 2026 - added a commit that references this issue
on Sep 16, 2026 - added 5 commits that reference this issue
on Sep 17, 2026
Client or integration
Codex CLI (
ocx syncon a desktop install; the same refusal surfaces in the dashboard as the failed sync message)Area
Platform (Windows / macOS / Linux)
Summary
On a Simplified Chinese Windows host (console code page 936/GBK), with the proxy running manually — no
opencodex-proxyscheduled task, no WinSW service —ocx syncdeterministically refuses to write the Codex config:"Absent" is the expected ownership answer in this state (no service, no task), but the probe cannot prove it. Two gaps compound:
SCHTASKS_TASK_NOT_FOUND_EN(src/service-manager-probe.ts) matches only/cannot find the file specified/i. On zh-CN,schtasks /query /tn opencodex-proxy /xmlexits 1 with the GBK bytes of错误: 系统找不到指定的文件。— anddecodeWindowsTextBytescannot decode those bytes either, becauselegacyEncodingForLocale(src/lib/windows-text.ts) only mapsko → euc-krand the windows-1252 family. Chinese (and Japanese) bytes fall through to the UTF-8 fallback and arrive as mojibake, so the regex can never match.schtasks /query /fo CSV /nhis capped bySERVICE_PROBE_TIMEOUT_MS = 2000. Measured on this host: 401 scheduled tasks, 12.3 s for the full listing —spawnSyncreturnsETIMEDOUTinside the probe,registered: "unknown", and the write is refused.A second, related budget surfaces right after the first is worked around:
WINDOWS_POWERSHELL_LOOKUP_TIMEOUT_MS = 8000(src/codex/user-identity.ts). The lookup spawnspowershell.exe -NoLogo -NoProfile -NonInteractive -Commandincluding anAdd-TypeP/Invoke expression. Measured on this host: SID expression 3.2 s, LocalAppData (Add-Type) expression 4.6 s per spawn — with ordinary spawn jitter this intermittently exceeds 8 s and sync fails withCodexUserIdentityRefusal: Windows effective-account lookup timed out.The file's own CI constant already uses 30 000 ms for exactly this reason ("runner contention"), so the desktop ceiling is demonstrably marginal on contended real machines too.Expected: ownership on a task-less, service-less Windows host should be provable regardless of the OS UI language.
Reproduction
@bitkyc08/opencodex; run the proxy manually (ocx start); do not install the scheduled task (ocx service install).schtasks /query /fo CSV /nhtakes longer than 2 s (401 on this host), or simply observe the stderr encoding in step 4.ocx sync→ refused with the ownership message above. Under bun, callinginspectServiceManagerInstallation()reproduces it deterministically:{ "kind": "unknown", "reason": "Task Scheduler could not be asked whether opencodex-proxy is registered" }Evidence measured on the affected host (Windows 10 22H2, zh-CN, opencodex 2.35.0):
schtasks /query /tn opencodex-proxy /xml→ exit 1, stderr = 31 GBK bytes, correctly decodable vianew TextDecoder("gbk")(错误: 系统找不到指定的文件。), butdecodeWindowsTextBytesreturns mojibake (its legacy table lacks zh).schtasks /query /fo CSV /nh→ 401 tasks, 12.3 s wall time; inside the probe it is killed at 2 s (ETIMEDOUT).powershell.exe -NoProfile -Command exitcosts ~3 s on this machine vs ~150 ms on a typical desktop.Version
2.35.0 (installed via
npm install -g, bun runtime)Operating system
Windows 10 22H2 (build 19045), UI language zh-CN
Provider and model
Not provider-specific.
Logs or error output
Suggested fix
legacyEncodingForLocale: addzh → gbk(big5 for zh-Hant) andja → shift_jis— all WHATWG labels the runtime already exposes, so no new dependency.SCHTASKS_TASK_NOT_FOUND_ENwith the localized messages (e.g.找不到指定的文件,指定されたファイルが見つかりません), or make the absence check locale-independent.For reference, a local patch of exactly those three points was verified on the affected host: probe
unknown → absent, admissionrefused → admitted, andocx syncthen exits 0 (720 models written to the catalog).Checks