Skip to content
Latchkey

Python "UnicodeEncodeError" Printing to stdout in CI - Locale & PYTHONUTF8

Python tried to write a non-ASCII character to stdout, but the stream’s encoding is ASCII because the runner has no UTF-8 locale. Printing an emoji, accented name, or box-drawing character then crashes - only in CI.

What this error means

A print() (or logging) of text containing non-ASCII characters raises UnicodeEncodeError: 'ascii' codec can't encode character. The same code prints fine locally where the terminal locale is UTF-8.

Python traceback
UnicodeEncodeError: 'ascii' codec can't encode character '\u2713' in position 0:
ordinal not in range(128)
  File "report.py", line 12, in <module>
    print(f"{name} ✓")

Common causes

Non-UTF-8 locale makes stdout ASCII

With LANG=C/POSIX, Python (pre-3.15, outside UTF-8 mode) picks ASCII as the stdout encoding, so any non-ASCII output fails to encode.

Redirected output without a tty

When stdout is a pipe or file rather than a terminal, Python may fall back to the locale encoding, which on a bare runner isn’t UTF-8.

How to fix it

Enable UTF-8 mode

Python’s UTF-8 mode forces UTF-8 for stdio regardless of locale.

Terminal
export PYTHONUTF8=1
# or per command
python -X utf8 report.py

Set the IO encoding explicitly

Terminal
export PYTHONIOENCODING=utf-8
python report.py

Reconfigure the stream in code

As a last resort, reconfigure stdout at startup so the program is locale-independent.

Python
import sys
sys.stdout.reconfigure(encoding="utf-8")

How to prevent it

  • Set PYTHONUTF8=1 (and a UTF-8 LANG) in CI.
  • Don’t assume the terminal locale is UTF-8 on minimal runners.
  • Reconfigure stdio encoding explicitly for tools that must emit Unicode.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →