Read and write AGENTS.md, CLAUDE.md and .gitignore as UTF-8 in reflex init

B8
15h ago
+70-5

All Submissions:

  • Have you followed the guidelines stated in CONTRIBUTING.md file?
  • Have you checked to ensure there aren't any other open Pull Requests for the desired changed?

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Changes To Core Features:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your core changes, as applicable?
  • Have you successfully ran tests with your changes locally?

What and why

reflex init writes the managed AGENTS.md section and the CLAUDE.md bridge, and merges .gitignore. It does this with Path.read_text() / write_text() and no encoding, so on Windows these files use the ANSI code page.

On Japanese Windows (cp932) with Python 3.11, a plain reflex init stops here:

UnicodeEncodeError: 'cp932' codec can't encode character '—' in position 161: illegal multibyte sequence

The canonical AGENTS.md contains an em dash. If an AGENTS.md, CLAUDE.md or .gitignore already has CJK text, the run fails with UnicodeDecodeError instead. On cp1252 the em dash can be encoded, so there is no error, but the file is saved as cp1252 instead of UTF-8.

This change passes encoding="utf-8" to those reads and writes, as path_ops.write_file and #6761 (reflex rename) already do. No other files are touched. Python 3.15 turns on UTF-8 mode by default, but 3.11 to 3.14 still use the locale encoding.

Tests: three new unit tests in tests/units/utils/test_utils.py use non-ASCII content. With cp932 they fail without the fix (UnicodeEncodeError / UnicodeDecodeError) and pass with it. Their strings can't be encoded or decoded as cp1252 either, so they would fail on the Windows CI runners without the fix. A towncrier fragment is in news/.

I used Claude Code to write this change.