GPT Cleanup

Zero-Width Space in Code: Why It Looks Right but Fails

Code copied from a chat, a PDF, or a web page can carry invisible Unicode that looks identical to normal text but breaks parsers, comparisons, and lookups.

The symptom

You copy a variable name, a config key, or a shell command from somewhere — an AI chat, a Stack Overflow answer, a PDF — paste it into your editor, and it looks completely correct. Then the code fails. ReferenceError: myVar is not defined even though myVar is right there on the line above. A JSON file throws Unexpected token at position 0. A Python script dies with SyntaxError: invalid non-printable character U+00A0. A shell command reports command not found for a command that is spelled correctly. A spreadsheet VLOOKUP or a deduplication script silently fails to match two cells that look identical.

In every one of these cases, the two strings are not actually identical. One of them contains an invisible Unicode character that your eyes cannot see but the parser, interpreter, or comparison operator treats as a real, distinct character.

Where it comes from

These characters do not appear when you type. They arrive through copy-paste, most commonly from: AI chat interfaces like ChatGPT, Claude, and Gemini (their rich-text renderers use invisible characters for cursor positioning and streaming); Stack Overflow and other formatted web answers; PDFs, where text extraction often inserts non-breaking spaces at line-wrap points; Slack and Notion, which store rich text internally and leak formatting artifacts on copy; and general web pages, where non-breaking spaces are used deliberately for layout.

Which characters cause it

CharacterCode pointTypical failure
Zero Width SpaceU+200BSplits an identifier into two tokens; breaks string equality
Zero Width Non-JoinerU+200CSame as above; rarer, usually from Persian/Arabic/Indic source text
Zero Width JoinerU+200DSame as above; legitimate only inside emoji sequences
Word JoinerU+2060Silently breaks tokenization and string matching
Byte Order Mark / ZWNBSPU+FEFFAt file start: breaks JSON.parse and shebang lines. Mid-string: acts like a zero-width space
No-Break SpaceU+00A0Python: SyntaxError: invalid non-printable character U+00A0
Soft HyphenU+00ADSplits words copied across a line wrap in a PDF or web page
LTR/RTL MarkU+200E / U+200FBreaks matching in bidirectional or mixed-language strings

Language-specific examples

In the samples below, ⟨U+200B⟩ marks where an invisible character sits; in real code there is nothing to see at that position.

JavaScript — a zero-width space inside a variable name produces a reference that looks like a duplicate but is not:

const total⟨U+200B⟩ = 42; // "total" here has a trailing U+200B
console.log(total); // ReferenceError: total is not defined

Python — a non-breaking space pasted in place of a regular space is a hard syntax error, not a silent bug:

if x == 1:
    print("ok") # the space before print may be U+00A0
# SyntaxError: invalid non-printable character U+00A0

JSON — a leading byte order mark makes an otherwise valid file unparseable:

⟨U+FEFF⟩{"key": "value"}
// SyntaxError: Unexpected token in JSON at position 0

Bash / .env files — a trailing zero-width space on an environment variable name breaks lookups silently:

API_KEY⟨U+200B⟩=sk-abc123
# API_KEY (with trailing U+200B) is not the same variable as API_KEY
# process.env.API_KEY is undefined; command aliases fail with "command not found"

SQL and spreadsheets — a non-breaking space in a value pasted from a web page or PDF makes a WHERE email = 'user@example.com' clause or a VLOOKUP return no match, even though the cell displays the correct text.

How to find them

On the command line, cat -A or cat -v reveals non-printable bytes that a plain cat hides. A targeted search with grep -P '[\x{200B}\x{FEFF}]' finds specific code points across a file or directory. In VS Code, turn on "Render Control Characters" and the editor.unicodeHighlight settings, which highlight unusual Unicode in yellow as you type or open a file. In Python, [hex(ord(c)) for c in s if ord(c) > 127] lists every non-ASCII character in a string with its code point. In JavaScript, str.replace(/[\u200B-\u200D\uFEFF]/g, "") both detects (via a changed length) and strips the common zero-width set.

Removing them in bulk

For a one-off cleanup, paste the snippet into our zero-width space remover. The raw view shows each hidden character with its code point and position in the string, and cleaning strips them in one pass. One exception worth knowing: U+200D (zero-width joiner) is legitimate inside emoji sequences — it is what joins separate emoji into a combined glyph — so the tool keeps it there and only removes it when it appears in plain text.

Preventing it

When pasting from a chat or a web page into code, use your editor's "paste as plain text" shortcut where available — this avoids picking up the HTML clipboard layer, though it does not strip already-embedded invisible characters from the plain-text layer itself. Turn on Unicode highlighting in your editor so these characters are visible as you work instead of surfacing later as a runtime error. For teams, a pre-commit hook running a regex grep for the common zero-width and no-break characters catches them before they reach a shared branch.