AskUserQuestion: Korean text in question/header/label/description renders corrupted, but preview field is unaffected

Open 💬 0 comments Opened Jul 9, 2026 by kcdralph

Summary

AskUserQuestion's question/header/label/description text fields render corrupted Korean (Hangul) characters in the terminal — but the tool's preview field, rendered in the same tool call on the same screen, is unaffected. The session stays fully usable (unlike anthropics/claude-code#68325, where a similar corruption class permanently bricked the session); only the on-screen text is wrong.

Environment

  • Claude Code CLI on macOS
  • Running inside cmux (tmux-based terminal multiplexer)
  • Korean-language session

Reproduction

Called AskUserQuestion with plain, correctly-encoded Korean strings (verified beforehand by writing them to a file and diffing — no typo on the caller side):

{
  "questions": [{
    "question": "확인",
    "header": "라벨",
    "options": [
      {"label": "다", "description": "다"},
      {"label": "아니요", "description": "아니요"}
    ],
    "multiSelect": false
  }]
}

Rendered in the terminal as:

□ 럼틀        <- header "라벨" corrupted to "럼틀"
황인          <- question "확인" corrupted to "황인"
❯ 1. 다
     다
  2. 아니요
     아니요

Note these are not replacement characters (/U+FFFD) — each corrupted string renders as a different, valid-looking Hangul syllable. Other examples observed in the same session:

  • "확인" → "황인"
  • "라벨" → "럼틀"
  • longer sentences: multi-syllable words scrambled at the jamo level throughout, e.g. "여러 포트를 대상해밀니다" style scrambling across an entire long description string

Key isolating clue: preview field is immune

In a separate call in the same session, the tool call also included a preview field (rendered as a separate monospace/markdown box). That field's Korean text — including multi-line, word-wrapped text — came through perfectly intact, while question/header/label/description in the same tool call, same screen, same terminal, same font were corrupted.

This rules out terminal/font/locale/wide-character-width causes, which would corrupt all Korean text on screen uniformly. It points specifically at whatever code path renders question/header/label/description for AskUserQuestion — as opposed to preview, which appears to go through a different (markdown) renderer.

Relation to #68325

anthropics/claude-code#68325 documents a related-looking failure: a lone UTF-16 surrogate emitted inside an AskUserQuestion description field, which got persisted into the session JSONL and eventually bricked the session with repeated HTTP 400 "no low surrogate" errors. That report's root-cause theory (a UTF-8 Hangul codepoint near the surrogate-adjacent BMP range getting corrupted into an unpaired surrogate during model output / tool-call serialization) may be the same mechanism at work here.

However, this report differs in a way that seemed worth splitting out rather than appending as a comment:

  • Severity: #68325 permanently kills the session (data corruption persisted to disk, poisons every subsequent API call). This report's sessions continued normally — the corruption appears to be render-only, not persisted/API-breaking.
  • New clue: the preview-field immunity above isn't mentioned in #68325 and suggests the bug may be reproducible/isolable at the rendering layer specifically for AskUserQuestion's non-preview text fields, independent of whatever is happening at the serialization layer in #68325.

Filing separately in case they turn out to be distinct bugs (or distinct enough to need separate fixes at the render vs. serialization layer) — happy to have this merged/closed as a duplicate if maintainers determine it's the same root cause.

Suggested investigation

  • Diff the code path that renders AskUserQuestion's question/header/label/description fields against the one used for preview, to find where they diverge for CJK text.
  • Check whether the divergent path does any string manipulation (truncation, word-wrap, byte-level slicing) that could split a multi-byte UTF-8 Hangul sequence mid-codepoint.

Happy to provide full raw tool-call JSON / additional screenshots if useful.

View original on GitHub ↗