Unicode debugging guide · October 14, 2026
Zero Width Space: Why Invisible Text Breaks Code—and When Not to Remove It
Direct answer: A zero width space (ZWSP, U+200B) is invisible, but it remains part of the text. It can break a pasted URL, trigger a syntax error, or change how a renderer wraps a line. It can also be intentional: Unicode defines it as an invisible line-break opportunity, including for scripts that do not ordinarily separate words with visible spaces. The right fix depends on where it appears—not simply on whether it is invisible.
One character, several different failures
In one Python example, code copied with U+200B produced:
SyntaxError: invalid character in identifier
A hex dump showed the UTF-8 bytes E2 80 8B. Those bytes are a useful fingerprint when the editor makes the character impossible to see. A separate report using Python 3.8.1 and VS Code showed a different failure: printing scraped text to a Windows console raised UnicodeEncodeError because the console's cp1252 encoding could not represent \u200b. The first problem was in source code; the second happened while output was being encoded. Treating both as a generic “bad whitespace” problem misses that distinction.
A pasted URL caused another kind of failure. In Visual Studio, HttpWebRequest.CreateHttp(string url) raised UriFormatException because the string began with a zero width space before the visible http. Turning on “View White Space” did not reveal it. In a JavaScript build, the error was more explicit:
line 178 col 48 Unexpected ''.
Deleting and retyping the affected line fixed that case. That is a practical first repair for a contaminated source line, but it is not a general rule for cleaning every user's text.
Do not assume the code point
A pasted value that looks identical to a manually typed value may contain a different invisible character. In one discussion, an identifier rejected when pasted worked when typed; inspection found two U+200C ZERO WIDTH NON-JOINER characters at the end—not U+200B. The distinction matters. A tool that only removes zero width spaces will miss them, while a broad “remove all invisible characters” rule can remove characters a language or layout needs.
If typing works but pasting fails, compare the actual code points in both values before changing validation logic. A Unicode inspector or an editor that highlights invisible characters can help. VS Code added invisible-Unicode highlighting in version 1.63; that is useful for source files, but it does not prove that every invisible character in every editor or document format will be shown.
Sometimes the invisible character is doing its job
U+200B is not inherently junk. Unicode describes it as providing an invisible line-break opportunity, including in languages such as Thai, Khmer, and Japanese. Removing it from a localization string may change line wrapping even though the visible words appear unchanged.
There is an important edge case: support can differ between renderers. In one Defold discussion, Japanese, Chinese, and Korean text had zero width spaces between characters. The regular text elements wrapped as expected, but the Rich Text element did not. A participant suspected the rich-text code was looking for the literal &zwsp; entity instead of the Unicode character. That was a suspicion, not a confirmed diagnosis—but it points to a useful test: compare the same input in plain text and rich text before rewriting the localization data.
The right cleanup rule depends on the field: an identifier usually needs exact code points, while a localized text run may need its invisible break markers preserved. For code, URLs, IDs, and configuration values, inspect and remove only the confirmed unwanted character. For text whose layout depends on invisible break points, preserve the original and test the destination renderer first.
If you are checking copied AI text, Claude Text Cleaner can show and remove characters in its supported list in your browser. Review the result against the original before using it; a cleanup count does not identify where a character came from or whether it was intentional.
A short diagnostic sequence
- Keep an untouched copy of the original.
- Reproduce the failure with the pasted value, then compare it with a manually typed value.
- Inspect code points; for U+200B, the UTF-8 byte sequence is
E2 80 8B. - Identify whether the failure occurs in parsing, validation, console output, or rendering.
- Remove only the unwanted character, then test the original operation again.
Related guide: How to check Claude text for hidden characters.