Skip to content

3D generation hangs forever on Japanese Windows: extension worker deadlocks when stderr reader thread dies with UnicodeDecodeError (cp932) #214

Description

@Haagen-kaz

Environment

  • Windows 11 Pro (Japanese locale, default console codepage cp932)
  • Modly with the hunyuan3d-mini-fast extension (torch 2.6.0+cu124, RTX 3060)

Symptom

On a Japanese-locale Windows machine, every 3D generation gets stuck forever (worker process at 0% CPU, never finishes). The UI progress bar sits around ~80%, but that part of the bar is smoothed/estimated progress, so the hang is easy to misread as "slow generation".

Root cause

In api/services/extension_process.py, the worker is spawned with subprocess.Popen(..., text=True) without an explicit encoding=. With text=True, Python uses the OS locale encoding for the pipes — cp932 on Japanese Windows.

The worker emits UTF-8 (and mixed-encoding output from native libs). As soon as a non-cp932 byte sequence arrives, the _stderr_loop reader thread dies with UnicodeDecodeError. With the reader thread dead, the stderr pipe fills up, and the worker then blocks forever inside a tqdm write mid-generation. From the outside it looks like a silent, permanent stall (CPU 0%).

Fix (verified locally)

Two small changes make generation work reliably on cp932 systems:

--- a/api/services/extension_process.py
+++ b/api/services/extension_process.py
@@ class ExtensionProcess:
         env["MODLY_API_DIR"] = str(Path(__file__).parent.parent)
+        # Force the worker's Python stdio to UTF-8 so it matches the utf-8
+        # pipe readers regardless of the OS locale (e.g. cp932).
+        env["PYTHONUTF8"] = "1"
@@ class ExtensionProcess:
             self._proc = subprocess.Popen(
                 [str(python), str(_RUNNER_PATH)],
                 stdin=subprocess.PIPE,
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE,
                 text=True,
+                encoding="utf-8",
+                errors="replace",
                 bufsize=1,
                 env=self._build_env(),
             )
  • encoding="utf-8" makes the pipe readers independent of the OS locale.
  • errors="replace" keeps the reader threads alive even on mixed-encoding output from native libraries.
  • PYTHONUTF8=1 makes the worker side symmetric.

With this patch applied locally, generation completes normally on the same machine. This likely affects all non-UTF-8-locale Windows users (Japanese, Chinese, Korean, ...). Happy to open a PR if useful.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions