Description
hermes claw migrate crashes with UnicodeDecodeError on Windows systems where the default encoding is not UTF-8 (e.g. GBK on Chinese Windows). The migration fails during the preview phase, making it impossible to migrate from OpenClaw.
Environment
- OS: Windows 11 Pro (Chinese locale, default encoding: GBK / cp936)
- Python: 3.12
- Hermes Agent: installed via
irm .../install.ps1 | iex
- OpenClaw directory contains: config files, markdown, images (.jpg), audio (.ogg), SQLite database (memory/main.sqlite)
Steps to Reproduce
- Install Hermes Agent on a Windows machine with a non-UTF-8 default locale (e.g. Chinese, Japanese, Korean)
- Have an existing OpenClaw installation at
~/.openclaw that contains binary files (images, SQLite, etc.)
- Run
hermes claw migrate or hermes claw migrate --dry-run
Expected Behavior
The migration should complete successfully, skipping binary files and handling encoding differences gracefully.
Actual Behavior
The migration crashes immediately during preview:
┌─────────────────────────────────────────────────────────┐
│ ⚕ Hermes — OpenClaw Migration │
└─────────────────────────────────────────────────────────┘
◆ Migration Settings
Source: C:\Users\admin\.openclaw
Target: C:\Users\admin\AppData\Local\hermes
Preset: full
Overwrite: no (skip conflicts)
Secrets: yes (allowlisted only)
✗ Migration preview failed: 'utf-8' codec can't decode byte 0xb3 in position 23114: invalid start byte
This happens with both --preset full and --preset user-data.
Root Cause
Several file-reading functions in openclaw_to_hermes.py use path.read_text(encoding="utf-8") without error handling. A typical OpenClaw directory contains binary files (images in media/, SQLite in memory/, etc.) and potentially text files written with the system's default encoding. When any of these are read as strict UTF-8, the entire migration aborts.
Affected functions:
read_text() (line 295) — no error handling at all
load_yaml_file() (line 330) — catches YAML errors but not encoding errors
parse_env_file() (line 347) — no error handling
load_openclaw_config() (line 954) — catches JSONDecodeError but not UnicodeDecodeError
migrate_daily_memory() (line 1573) — iterates .md files with no per-file error recovery
Additional Note
There is also a separate issue where hermes-agent.exe itself crashes on non-UTF-8 Windows due to emoji output:
UnicodeEncodeError: 'gbk' codec can't encode character '\U0001f916' in position 0: illegal multibyte sequence
This can be worked around with $env:PYTHONUTF8 = "1" and chcp 65001, but ideally the CLI should handle this gracefully too (e.g. via PYTHONIOENCODING=utf-8 in the launcher or a colorama init fix).
Fix
PR #8898 addresses the migration script issues by:
- Adding
errors="replace" to read_text() so invalid bytes become U+FFFD instead of crashing
- Adding
UnicodeDecodeError to except clauses in load_yaml_file, parse_env_file, and load_openclaw_config
- Adding per-file try/except in
migrate_daily_memory to skip unreadable files
Tested on the same Windows 11 Chinese locale machine — after the fix, hermes claw migrate --dry-run completes successfully and correctly identifies 44 items for migration.
Description
hermes claw migratecrashes withUnicodeDecodeErroron Windows systems where the default encoding is not UTF-8 (e.g. GBK on Chinese Windows). The migration fails during the preview phase, making it impossible to migrate from OpenClaw.Environment
irm .../install.ps1 | iexSteps to Reproduce
~/.openclawthat contains binary files (images, SQLite, etc.)hermes claw migrateorhermes claw migrate --dry-runExpected Behavior
The migration should complete successfully, skipping binary files and handling encoding differences gracefully.
Actual Behavior
The migration crashes immediately during preview:
This happens with both
--preset fulland--preset user-data.Root Cause
Several file-reading functions in
openclaw_to_hermes.pyusepath.read_text(encoding="utf-8")without error handling. A typical OpenClaw directory contains binary files (images inmedia/, SQLite inmemory/, etc.) and potentially text files written with the system's default encoding. When any of these are read as strict UTF-8, the entire migration aborts.Affected functions:
read_text()(line 295) — no error handling at allload_yaml_file()(line 330) — catches YAML errors but not encoding errorsparse_env_file()(line 347) — no error handlingload_openclaw_config()(line 954) — catchesJSONDecodeErrorbut notUnicodeDecodeErrormigrate_daily_memory()(line 1573) — iterates.mdfiles with no per-file error recoveryAdditional Note
There is also a separate issue where
hermes-agent.exeitself crashes on non-UTF-8 Windows due to emoji output:This can be worked around with
$env:PYTHONUTF8 = "1"andchcp 65001, but ideally the CLI should handle this gracefully too (e.g. viaPYTHONIOENCODING=utf-8in the launcher or acoloramainit fix).Fix
PR #8898 addresses the migration script issues by:
errors="replace"toread_text()so invalid bytes become U+FFFD instead of crashingUnicodeDecodeErrorto except clauses inload_yaml_file,parse_env_file, andload_openclaw_configmigrate_daily_memoryto skip unreadable filesTested on the same Windows 11 Chinese locale machine — after the fix,
hermes claw migrate --dry-runcompletes successfully and correctly identifies 44 items for migration.