Skip to content

Windows Korean user paths are decoded as UTF-8, blocking service ownership and Codex sync #1573

Description

@xcbyte-cmyk

Summary

On a Korean Windows installation, OpenCodex 2.14.0 decodes some Windows command output as UTF-8 even when the output is CP949/EUC-KR. A Korean user-profile path is therefore replaced with U+FFFD characters, causing service ownership checks and Codex write coordination to fail.

This prevents ocx sync from injecting model_catalog_json and openai_base_url, even though the proxy and provider routing themselves are healthy.

Environment

  • OpenCodex: 2.14.0, installed globally via npm
  • Codex CLI: 0.145.0
  • Runtime: bundled Bun 1.3.14
  • OS: Windows with Korean system locale
  • User profile shape: C:\Users\<Korean username>\...

Symptoms

The first failure is the scheduled-task ownership probe:

Refusing to write because ownership could not be proven: the scheduled-task XML names
C:\Users\���ȭ��_��������\.opencodex\opencodex-service-launcher.vbs,
outside the expected launcher directory
C:\Users\<Korean username>\.opencodex.

After fixing that decoding site locally, the next failure is:

Codex configuration was not written: the coordinator path could not be resolved:
CodexUserIdentityRefusal: The Windows coordinator namespace cannot be created.

The nested cause shows that the LocalAppData path was corrupted in the same way:

EPERM: operation not permitted, mkdir 'C:\Users\���ȭ��_��������'

Running ocx service repair does not resolve either issue because the generated files are valid UTF-16LE; the corruption occurs while decoding child-process output.

Root cause

There appear to be two affected decoding sites:

  1. src/service-manager-probe.tsdecodeWindowsText()

    • UTF-16LE/BE is handled.
    • The remaining fallback uses buffer.toString("utf8").
    • schtasks /query /xml output can be CP949 on Korean Windows.
  2. src/codex/user-identity.tspowershellValue()

    • new TextDecoder().decode(result.stdout) assumes UTF-8.
    • PowerShell known-folder output can be CP949 under this locale.

Reproduction

  1. Use a Windows account whose profile path contains Korean characters.
  2. Install OpenCodex 2.14.0 and its background service.
  3. Configure a custom provider.
  4. Run:
ocx service repair
ocx sync
  1. Observe that synchronization is refused with the errors above.

Validated local workaround

I added an EUC-KR fallback when UTF-8 decoding contains U+FFFD at both sites.

const utf8 = buffer.toString("utf8").replace(/^\uFEFF/, "").trim();
if (utf8.includes("\uFFFD")) {
  try {
    return new TextDecoder("euc-kr").decode(buffer).replace(/^\uFEFF/, "").trim();
  } catch {
    // Keep the original UTF-8 decoding when the runtime lacks the Windows codec.
  }
}
return utf8;

And for PowerShell output:

let value = new TextDecoder().decode(result.stdout).trim();
if (value.includes("\uFFFD")) {
  try {
    value = new TextDecoder("euc-kr").decode(result.stdout).trim();
  } catch {
    // Keep the original UTF-8 decoding when the runtime lacks the Windows codec.
  }
}

After applying both changes:

  • ocx sync completed successfully.
  • 427 custom-provider models were appended to the Codex catalog.
  • model_catalog_json and openai_base_url were injected.
  • A request through Codex/OpenCodex/custom provider completed successfully.

Expected behavior

OpenCodex should preserve non-ASCII Windows paths regardless of the active Windows locale/code page. Ideally, child commands should be forced to emit a known encoding, or their output should be decoded using the detected Windows code page rather than assuming UTF-8.

I can provide the complete two-file patch if useful.

Activity

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 workingplatformOS/service/tray/ACL (Windows-heavy, not Windows-only)serviceService lifecycle (WinSW/launchd/scheduler)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions