GPT Watermark Remover — Clean Invisible Unicode from AI Output
Strip stray Unicode from generated text before it goes into your CMS, your spreadsheet or your repository.
Hidden character report
Paste text to scan
Where generated text picks up stray characters
Generated answers arrive through a rendering layer, and that layer leaves marks. Line-break hints become zero-width spaces. Emoji sequences get joined with invisible characters. Mixed-direction phrases pick up embedding controls. None of this is visible in the chat window, and all of it is visible to whatever you paste into next. The characters travel silently from the AI interface to your clipboard to your editor, and each hand-off can add its own layer of formatting noise on top.
The second source is your own toolchain. Copying from a rendered page, then from a word processor, then into a web form, stacks up three different notions of what a space is. By the time the text reaches a database column, a single paragraph can contain four kinds of whitespace and none of them behave the same way. Cleaning at the last step, right before the content goes somewhere that matters, is the most reliable point to intervene.
The characters this tool strips
Six zero-width characters, twelve bidirectional controls, the soft hyphen, and the carriage return. Three invisible space variants are not deleted but normalised to an ordinary space, because deleting them would silently glue two words together. The full table is on the page, with a code point for each entry.
Formatting residue is handled separately and counted separately: runs of two or more spaces become one, and three or more consecutive line breaks become two. That is what fixes the doubled spacing people see after pasting a generated answer into an editor.
Cleaning generated text for a publishing workflow
Paste the draft, press Clean, and read the report before you copy. A long list of zero-width spaces usually means the text came straight from a chat window with no intermediate editing. A short list with one or two non-breaking spaces usually means it passed through a word processor.
The report is the useful part. It tells you which step of your own pipeline is introducing noise, which is something you can fix upstream instead of cleaning up afterwards forever.
A five-second check before you publish
Headlines are where invisible characters do the most damage. A non-breaking space inside a title will not wrap the way your layout expects, and a directional control can reorder the punctuation around it. Paste the headline alone and check the report before the full article.
For anything machine-read — CSV exports, search indexes, log matching — the same check applies. An invisible character is enough to make two strings that look identical compare as different, and that failure is expensive to debug after the fact.
The six invisible characters GPT output actually carries
U+200B is the zero-width space — it has no width and no visual representation, but it breaks a word at that point for line-wrapping purposes. Chat interfaces insert it to hint where a long URL or code identifier can break across a line. When you copy the answer, the hint comes with it. The most common place to encounter it is inside a GPT-generated URL or a long technical term that the renderer decided might overflow its container.
U+200C (zero-width non-joiner) and U+200D (zero-width joiner) show up when the model has been trained on text in Arabic, Devanagari, or other scripts where glyph-joining rules matter. They are structural characters for those scripts and are meaningless noise when they end up inside plain English output. If your content passes through a multilingual CMS, these characters can also enter from a field that was edited in a right-to-left language before being overwritten with English.
U+FEFF started life as the Unicode byte-order mark. Modern usage sometimes repurposes it as a zero-width no-break space, and some rendering pipelines emit it at the start of a text block. You will never see it, but a parser that is not expecting it will either skip it silently or throw an encoding error, depending on how strict it is. Files exported from certain Windows applications are especially prone to carrying a leading BOM, and if you paste the contents of such a file into your generated draft, the BOM comes along for the ride.
U+00A0 is the non-breaking space. It looks identical to an ordinary space on screen, but it prevents line-wrapping and it does not match the \s pattern in most regex engines. This one travels through word processors more than it travels through AI output directly, but if your draft went through a copy-paste chain, U+00A0 can end up anywhere. It is particularly common in dates and measurements — '10 MB' typed in a quality-conscious editor often uses a non-breaking space to keep the number and unit together on one line.
U+00AD is the soft hyphen — a hyphenation hint that is invisible unless the word actually needs to break across a line. Its most common source is text scraped from a professionally typeset document where a typographer set manual break points. Like U+00A0, it is usually harmless on screen but silently corrupts string comparisons and search index terms. A soft hyphen inside a product name means that name will not match a search for that name, which is a hard bug to catch because both strings look right in every editor you use to inspect them.
Watermark or rendering noise — what the evidence actually says
There is no public evidence that OpenAI or any major AI provider embeds deliberate watermarks using invisible Unicode characters. The idea circulates frequently online, but no researcher has produced a reproducible method for identifying or extracting such a signal from ChatGPT output. The invisible characters in generated text have boring, verifiable explanations: rendering layers, markdown parsers, and copy-paste toolchains. If you run the same generated text through a Unicode inspector in two different browsers, you will often see different invisible character counts, because the browser's rendering layer itself is a source.
Real AI watermarking research does exist, but it works at the statistical level — slightly shifting which tokens the model chooses during generation so that the resulting text carries a detectable bias across thousands of words. That approach, proposed in academic papers by researchers at Google and elsewhere, leaves no per-character footprint that a Unicode cleaner can find or remove. Stripping zero-width spaces from your draft does not defeat a statistical watermark, because there is nothing there to strip. The statistical signal is baked into word choice, not hidden in Unicode code points.
What the cleaner is actually solving is a toolchain hygiene problem, not a detection problem. Generated text accumulates Unicode noise from the interface that rendered it, from the clipboard, and from any editor the text passed through before reaching you. That noise is real, it causes real bugs, and cleaning it is useful — but calling it a watermark overstates what is actually known about how these characters got there. The practical value of removing them is the same regardless of what you call the source.
Checking for invisible characters in Word, Google Docs, and VS Code
In Microsoft Word, turn on formatting marks with Ctrl+Shift+8 on Windows or Cmd+8 on Mac. That reveals ordinary spaces, paragraph marks, and tabs, but it does not surface zero-width characters or the soft hyphen. To find those, open Find & Replace (Ctrl+H), enable More options, check Use wildcards, then search for [\x{200B}\x{200C}\x{200D}\x{FEFF}\x{00AD}] — Word supports Unicode hex ranges in wildcard mode. Replace with nothing. Non-breaking spaces show up as a degree-symbol lookalike in the formatted view; find them with Ctrl+H using the special characters menu at the bottom of the dialog. If you are on an older version of Word that does not support Unicode wildcard ranges, the alternative is to paste the text into Notepad first — Notepad's plain-text paste will preserve the invisible characters but strip all formatting, making it easier to then copy into a dedicated Unicode inspector.
Google Docs has no native view for invisible Unicode. The most reliable approach is to open Find and Replace with Ctrl+H, check the Regular expressions box, and search for [\u200B\u200C\u200D\uFEFF\u00AD] — Docs uses RE2 syntax, which accepts \u hex escapes. Replace with an empty string. For non-breaking spaces, search for \u00A0 and replace with a plain space. Do this before pasting text anywhere that treats your document as source material. If you collaborate on documents where multiple editors paste in content from different sources, it is worth running this check at the start of any final editing pass rather than waiting until you are ready to publish. Invisible characters accumulate silently across revision history and you will not notice them until something downstream breaks.
In VS Code, set editor.renderWhitespace to all in your settings to make ordinary spaces and tabs visible. Zero-width characters are trickier — VS Code will render a thin highlighted block for U+200B and related characters if you have a font that supports the rendering, but not all fonts do. The most reliable check is to open the Find widget (Ctrl+F), click the regex toggle, and search for [\u200B-\u200D\uFEFF\u00AD\u00A0]. The match count in the corner tells you whether you have any. From there you can use Find and Replace to remove them before committing the file. If you work with generated content regularly, it is worth adding a pre-commit hook that runs a quick regex check and blocks commits when zero-width characters are present in prose files — a five-line shell script handles this and it pays for itself the first time it catches a bad paste before it reaches a code review.
What to check before and after running the cleaner
Before you clean anything that is going into production, keep a copy of the original. The cleaner is non-destructive in the sense that it only removes characters from a specific list, but if that list overlaps with something your system depends on — a zero-width joiner inside a custom emoji sequence, for example — you want the ability to compare before and after without re-generating the content. For long-form articles that took multiple rounds of editing to produce, that comparison can save a lot of time if something downstream starts behaving unexpectedly.
After cleaning, read the report line by line rather than just checking that the count went to zero. A cluster of fifty zero-width spaces in one paragraph usually means that paragraph was copied from a different source than the rest of the article. That is a workflow signal, not just a cleanup task: the next time you pull content from that source, the same problem will appear. Fixing it once at the source is faster than cleaning it every time. The report groups characters by type and gives you a position for each one, which makes it possible to trace back to the specific paragraph where the noise entered.
Pay specific attention to URLs and code samples in the cleaned output. A zero-width space inside a URL makes it visually correct but functionally broken — the browser or the HTTP client will either reject it or encode the zero-width character as %E2%80%8B, which almost certainly does not resolve to anything. Copy any URLs from the cleaned output and test them before publishing. The same caution applies to anything that will be parsed as code: an invisible character inside a regular expression or a command-line argument will fail in a way that is genuinely difficult to diagnose without knowing what to look for. A brief test run is much cheaper than a late-night debugging session because a string comparison silently fails in production.
One thing to check after cleaning is whether any intentional formatting survived. Non-breaking spaces in measurements like '2.4 GHz' or '10 km' keep the number and unit together. If those were U+00A0 in the original, they are gone after cleaning and the text may now wrap awkwardly in narrow containers. The cleaner normalises these to ordinary spaces, which is the right default for most workflows, but it is worth a visual scan on anything where layout precision matters.
Characters this tool looks for
25 invisible characters and formatting controls, with the action taken on each one.
| Character | Code point | Action | What it does |
|---|---|---|---|
| Zero-width characters | |||
| Zero Width Space | U+200B | Removed | Invisible separator with no width. Commonly left behind when text is copied out of a chat window. |
| Zero Width Non-Joiner | U+200C | Removed | Invisible character that blocks two letters from joining in scripts such as Arabic or Devanagari. |
| Zero Width Joiner | U+200D | Removed | Invisible character used to glue emoji sequences together. Stray copies can break word wrapping. |
| Zero Width No-Break Space (BOM) | U+FEFF | Removed | Byte order mark. Harmless at the start of a file, invisible noise anywhere else. |
| Word Joiner | U+2060 | Removed | Tells a text engine not to break a line here. Invisible, and easy to carry along by accident. |
| Mongolian Vowel Separator | U+180E | Removed | A legacy invisible separator from Mongolian script that now renders as nothing at all. |
| Bidirectional controls | |||
| Left-to-Right Mark | U+200E | Removed | Directional hint for mixed-script lines. Invisible on screen but present in the character stream. |
| Right-to-Left Mark | U+200F | Removed | Mirror of the left-to-right mark, used to steer the order of mixed-direction text. |
| Arabic Letter Mark | U+061C | Removed | Invisible directional marker for Arabic text. Rarely intentional outside its original document. |
| Left-to-Right Embedding | U+202A | Removed | Opens an embedded left-to-right run. Unpaired copies can scramble the order of a sentence. |
| Right-to-Left Embedding | U+202B | Removed | Opens an embedded right-to-left run. Left behind after copy-paste, it can flip nearby punctuation. |
| Pop Directional Formatting | U+202C | Removed | Closes an embedded directional run. Without its partner it is pure invisible noise. |
| Left-to-Right Override | U+202D | Removed | Forces following characters to display left-to-right regardless of their own direction. |
| Right-to-Left Override | U+202E | Removed | Forces following characters to display right-to-left. A common cause of text that looks reversed. |
| Left-to-Right Isolate | U+2066 | Removed | Modern replacement for the embedding controls. Still invisible, still travels with copied text. |
| Right-to-Left Isolate | U+2067 | Removed | Isolates a right-to-left run from the surrounding paragraph direction. |
| First Strong Isolate | U+2068 | Removed | Isolates a run whose direction is decided by its first strong character. |
| Pop Directional Isolate | U+2069 | Removed | Closes an isolate opened by one of the isolate controls above. |
| Formatting controls | |||
| Soft Hyphen | U+00AD | Removed | A hyphen the reader only sees if the word happens to break at the end of a line. |
| Carriage Return (CR) | U+000D | Removed | Half of a Windows line ending. Kept on its own it produces doubled spacing in most editors. |
| Markdown Asterisk Marker | U+002A | Removed | Bold or italic marker such as ** left behind when text is copied in its raw form. Turn this group off to keep Markdown styling marks. |
| Markdown Backtick Marker | U+0060 | Removed | Inline-code backtick left behind after copying raw assistant output. Turn this group off to keep inline code marks. |
| Invisible spaces | |||
| No-Break Space | U+00A0 | → space | Looks exactly like a space but stops a line from breaking there. A frequent copy-paste leftover. |
| Figure Space | U+2007 | → space | A space as wide as a digit, used to align numbers in tables. Replaced with a normal space. |
| Narrow No-Break Space | U+202F | → space | A thin, non-breaking space from French typography. Replaced with a normal space. |
Frequently Asked Questions
▸Will this break my Markdown or code blocks?
No. Tabs, ordinary line breaks, indentation characters and all punctuation pass through untouched. The engine only acts on the characters in its published table, plus repeated spaces and blank lines. Zero-width characters inside code are removed, which is normally what you want.
▸Can I paste a whole article at once?
Yes. There is no fixed size limit. Very large inputs — a hundred thousand characters or more — are processed normally, with a short note in the report area to explain why it may take a moment longer. Everything still happens on your device.
▸Why do my line breaks look doubled after pasting?
That is almost always a carriage return. Windows line endings are two characters, and editors that only understand one of them render the leftover as an extra break. The engine removes the stray carriage return and leaves a single line feed, then collapses runs of three or more breaks down to two.