Skip to content

fix: don't crash printing emoji on a legacy Windows code page (FLYTE-SDK-7M) - #1456

Open
EngHabu wants to merge 1 commit into
mainfrom
fix/sentry-7m-console-encoding
Open

fix: don't crash printing emoji on a legacy Windows code page (FLYTE-SDK-7M)#1456
EngHabu wants to merge 1 commit into
mainfrom
fix/sentry-7m-console-encoding

Conversation

@EngHabu

@EngHabu EngHabu commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Sentry: FLYTE-SDK-7MUnicodeEncodeError: 'gbk' codec can't encode character '\U0001f680', release 2.6.2.
Sentry: FLYTE-SDK-7S — the same crash on cp1252, release 2.6.5.

What happens

flyte start devbox finishes bringing the cluster up, prints its success panel, and then dies:

flyte/cli/_devbox.py   launch_devbox
flyte/cli/_devbox.py   _launch_devbox_rich
rich/console.py        print
rich/_windows_renderer.py  legacy_windows_render
rich/_win32_console.py     write_text
UnicodeEncodeError: 'gbk' codec can't encode character '\U0001f680' in position 2

The panel prints 🚀 and 🐳. A Windows console on a regional code page (cp936 here, cp1252 in western locales) has no room for either, so the encode raises inside Rich's renderer — after the work succeeded. The user sees a crash instead of their cluster URL.

The fix

The repo already solves this for spinners: safe_spinner() (#1058) probes sys.stdout.encoding and falls back to "line" when the braille glyphs won't fit. This generalises that probe to arbitrary output.

safe_text() returns its input unchanged whenever stdout can already encode it — every UTF-8 terminal, so nothing changes for almost everyone. Otherwise it swaps the decorative glyphs the CLI actually emits for ASCII stand-ins (🚀/🐳 → dropped, ➡️ → ->, ⚠️!, ❌ → x) and replaces anything left over with ?, the same substitution errors="replace" would make. Rich markup is untouched, so links and colours survive.

Applied at the three sites that emit non-ASCII decoration:

site reached by
devbox ready panel flyte start devbox — the crash in Sentry
print_url() default ➡️ prefix flyte run, flyte rerun
home-directory warning flyte run --copy-style all from $HOME

print_url is worth calling out: it is on the mainstream flyte run path, so the same console would have crashed there next. The reporting user also has FLYTE-SDK-7P — their uploads fail behind a proxy — which is the only reason they had not reached it yet.

Also passes safe_spinner() to the devbox SpinnerColumn, which was the last spinner under flyte/cli still asking for Rich's braille default; cp936 cannot encode those either.

Verification

The new tests import safe_text, so on main they fail at collection and prove nothing on their own. Instead I ran a repro that renders each of the four sites to a strict cp936 stream, against clean origin/main and against this branch:

### clean origin/main ###
devbox panel   : CRASH -> UnicodeEncodeError: 'gbk' codec can't encode character '\U0001f680'   <- the Sentry signature
print_url      : CRASH -> UnicodeEncodeError: 'gbk' codec can't encode character '➡'
home warning   : CRASH -> UnicodeEncodeError: 'gbk' codec can't encode character '⚠'
devbox spinner : CRASH -> UnicodeEncodeError: 'gbk' codec can't encode character '⠋'

### this branch ###
all four: OK

12 new tests in tests/flyte/cli/test_safe_text.py, including three that drive a real rich.Console over a strict cp936 stream. tests/flyte/cli + tests/cli: 447 passed. ruff, mypy and check-docstrings clean.

Left alone deliberately

flyte/remote/_action.py:648 builds a SpinnerColumn() with the same braille default and would crash the same way. Fixing it means flyte.remote importing flyte.cli._common, which inverts the layering; it has no Sentry evidence yet, so it is called out here rather than bundled in.

Update: the cp1252 case arrived

This PR predicted "cp936 here, cp1252 in western locales". FLYTE-SDK-7S is exactly that, reported on release 2.6.5 from a different host: same _launch_devbox_rich panel, same \U0001f680, same rich/_win32_console.write_text frame — only the code page differs, which is why Sentry grouped it separately (the codec name is part of the message). No code change needed; it is the same defect and the same fix, so it is listed here so both close together.

fixes FLYTE-SDK-7M
fixes FLYTE-SDK-7S

…SDK-7M)

`flyte start devbox` dies with UnicodeEncodeError on a Windows console running a
regional code page. The success panel prints a rocket and a whale; cp936 has no
room for either, so the encode fails inside Rich's legacy-Windows renderer and
takes the command down after the cluster has already come up.

The repo already handles this for spinners (safe_spinner, #1058). This extends the
same probe to arbitrary output: safe_text() leaves text untouched whenever stdout
can encode it (every UTF-8 terminal), and otherwise swaps known decorative glyphs
for ASCII stand-ins and replaces anything left over with '?'.

Applied at the three sites that emit non-ASCII decoration:

* the devbox ready panel - the crash in Sentry
* print_url's default arrow prefix - reached by `flyte run` and `flyte rerun`,
  so the same console would have crashed there next
* the home-directory warning in `flyte run`

Also passes safe_spinner() to the devbox SpinnerColumn, which was the one spinner
in flyte/cli that still asked for Rich's braille default.

Verified against clean main with a repro that renders each of the four sites to a
strict cp936 stream: all four raise UnicodeEncodeError before this change and all
four render after it. (The new tests import safe_text, so on main they fail at
collection and prove nothing on their own.)

fixes FLYTE-SDK-7M

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
@EngHabu EngHabu added the sentry-fix Fix for an issue surfaced by Sentry label Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

sentry-fix Fix for an issue surfaced by Sentry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant