The text looks perfectly clean. Then search can't find a word that's clearly on the page, a CMS rejects a slug for "invalid characters", or a script fails on a string that appears identical to the one in your test. The cause is almost always invisible characters: real Unicode characters that occupy space in the text but render as nothing.
AI chatbots are a common source. Here's what these characters are, why models emit them, and how to get rid of them.
The usual suspects
Zero-width space (U+200B)
A space with no width. It sits between characters invisibly, splitting words in two as far as search and spell-check are concerned. This is the one people usually mean when they say "ChatGPT watermark".
Non-breaking space (U+00A0)
Looks exactly like a normal space, but it's a different character. It prevents line breaks, breaks number parsing, and makes "hello\u00A0world" fail a comparison against "hello world" — the first string carries the non-breaking space.
Byte order mark (U+FEFF, the BOM)
A byte-order signature meant for the start of files. When it lands in the middle of pasted text it can break JSON parsing and template rendering.
Also watch for these two:
- Directional marks (U+200E, U+200F and friends). Left-to-right and right-to-left controls for mixed-language text. In the wrong place they scramble the order of numbers and punctuation.
- Soft hyphen (U+00AD). An invisible hyphenation hint that only shows itself when a line wraps in the wrong spot.
AI output also carries visible-but-unwanted typographic characters: smart quotes, em dashes and single-character ellipses. Those are at least easy to see. The invisible set is what causes the confusing bugs.
Why AI models emit them
Mostly it's inheritance, not intent. Language models train on web pages, books, PDFs and code, all of which are full of typographic Unicode. The model reproduces what it learned. On top of that, chat interfaces and copy buttons sometimes insert zero-width or non-breaking spaces around formatted spans, and researchers have experimented with zero-width sequences as watermarking. The result is a paste that looks clean and isn't.
How invisible characters break things
Word processors and documents. Find and replace misses matches ("report" doesn't match "report" with a zero-width space inside), spell-check red-lines ordinary words, and non-breaking spaces make lines wrap in odd places.
CMSs and SEO. Hidden characters end up in slugs and URLs as ugly encoded sequences like %E2%80%8B. Internal site search misses affected words, and meta description length counts come out wrong.
Code and data. This is where it hurts most:
const a = 'hello\u200Bworld'; // contains a zero-width space
a === 'helloworld'; // false
JSON.parse('\uFEFF{"ok": true}'); // throws: BOM before the brace
Compilers report "unexpected token" on lines that look fine, CSV imports misalign, and string comparisons fail in tests. I've seen a deployment pipeline break because a config value copied from a chat window ended in a non-breaking space.
How to spot them
- The arrow-key test. Click into the suspicious word and walk the cursor across it with the arrow keys. If the cursor needs two presses to cross what looks like one position, there's an invisible character in between.
- The length check.
'hello world'.lengthshould be 11. If your pasted version reports 12 or 13, something extra is in there. - The encoding view. Pasting into a hex editor or an online Unicode inspector reveals every code point. Effective, but slow.
Honestly, none of these are fun at scale. The Invisible Character Viewer does the spotting for you: paste the text and every hidden character shows up as a labeled badge — code point on the badge, full Unicode name on hover — with a per-type count. One more click strips the whole set. Detection and removal should be the same step.
How to remove them
The AI Text Cleaner strips the full set in one pass: zero-width spaces, non-breaking spaces (converted to normal spaces), byte order marks, directional marks and soft hyphens. It also handles the visible leftovers from the same pastes: Markdown symbols, smart quotes and em dashes. Paste the text, copy the clean result, done. If the paste came from a document or a web page rather than a chat — styles, fonts, HTML tags — Remove Formatting strips that layer in the same one click.
If you're cleaning text in code, the core pattern is a small regex:
text = text
.replace(/[\u200B-\u200D\u200E\u200F\uFEFF\u00AD]/g, '')
.replace(/\u00A0/g, ' ');
The first line deletes the invisible characters, the second converts non-breaking spaces to regular ones.
The habit worth building
Any time text travels from a chatbot into a document, CMS, spreadsheet or codebase, clean it first. It takes two seconds with the AI Text Cleaner, runs entirely in your browser, and your text never leaves your device. That beats debugging an invisible character at 11pm. More guides like this one live on the AI text cleanup guides page.
Common questions about invisible characters in AI text
What is a zero-width space?
A real Unicode character (U+200B) that occupies a position in the text but renders as nothing. To you it looks like two letters sitting together; to a computer the word is split in two, so search, spell-check, and string comparisons all miss it. AI chats sometimes emit them between words, and copy buttons can insert them around formatted spans. The viewer above reveals every one with its code point.
How can I tell if my text has invisible characters?
Three quick signs: the arrow-key test (the cursor needs two presses to cross what looks like one position), a length check ('hello world'.length should be 11 — 12 means something extra), or a paste that breaks search or layout for no visible reason. The certain way is the Invisible Character Viewer: paste the text and every hidden character shows up as a labeled badge with its code point and count.
Why does ChatGPT put invisible characters in its answers?
Mostly inheritance, not intent. The models trained on web pages, books, and PDFs full of typographic Unicode and reproduce what they learned. Chat interfaces and copy buttons can also insert zero-width or non-breaking spaces around formatted spans. Researchers have proposed deliberate watermarking schemes too, but most of what you will find in a paste is typography, not a signature.
Will removing invisible characters change my text?
Only the parts you cannot see. The remover deletes zero-width and formatting characters and converts invisible spaces to regular spaces — your words, punctuation, and line breaks stay exactly as they were. Sentence for sentence the cleaned text reads identically; the character count difference is the whole change. If a rule ever removes something you wanted, turn that rule off and run it again.
How do I remove invisible characters in code?
Two lines cover the common set: text.replace(/[\u200B-\u200D\u200E\u200F\uFEFF\u00AD]/g, '') deletes zero-width and format characters, and text.replace(/\u00A0/g, ' ') converts non-breaking spaces to regular ones. For a whole document, the one-click remover on this site does the same pass without a script.