{"slug": "the-invisible-characters-hiding-in-your-ai-written-text", "title": "The invisible characters hiding in your AI-written text", "summary": "A developer building a job-search tool discovered that AI-generated text often contains invisible characters such as zero-width spaces, non-breaking spaces, and curly quotes, which can break searches, forms, and resume parsers. The developer built a cleaner to strip these characters, arguing that clean text is essential for portability and professionalism, and clarifying that removing them does not defeat AI watermarks.", "body_md": "You paste a paragraph from an AI chat into a job application. It looks clean. You submit it.\n\nWhat you cannot see is that a handful of characters came along for the ride: a zero-width space wedged between two words, a non-breaking space where a normal space should be, curly quotes instead of straight ones, and a dash that is technically a different character than the one on your keyboard. None of them show up on screen. All of them are really there.\n\nMost of the time this is harmless. Sometimes it quietly breaks things: a search that will not match, a copy-paste that renders a little box instead of a letter, a form that rejects your input for no reason you can see, or an applicant tracking system that parses your resume into nonsense. And lately it has a second life in the news, because those same invisible characters are showing up in conversations about AI watermarking and hidden text.\n\nI hit this problem enough while building my own job-search tool that I built a cleaner for it. Here is what is actually going on, and what I do about it.\n\nText on a computer is not just the letters you see. It is a stream of characters, and plenty of characters are designed to be invisible or nearly so. They exist for good reasons: to hold words together, to control spacing, to support languages that need them. The trouble starts when they get into your text without you knowing.\n\nA few common ways that happens:\n\nWhy should a normal person care? Because the places where your words matter most are often the pickiest:\n\nThis is not exotic. It is the digital equivalent of showing up to an interview with a price tag still on your sleeve. Small, invisible to you, and worth removing before anyone else notices.\n\nIf you follow AI news at all, you have probably seen two related stories.\n\nOne is **watermarking**: the idea that AI-generated text can carry hidden signals, sometimes as invisible characters, so it can be identified later. The other is **hidden text used to smuggle instructions**, where invisible characters are tucked into a document or a web page to quietly influence an AI system that reads it. Both are real, and both are worth understanding.\n\nI want to be clear about what this article is not. It is not a guide to defeating watermarks or dodging AI detectors. I think that is the wrong goal and, honestly, a losing game. My argument is simpler and older than any of this: **you should be able to see everything that is in your own writing, and you should be able to ship it clean.** Clean text is portable, professional, and predictable. Whether an invisible character came from a chat tool, a copy-paste, or a watermark, the fix is the same, and the reason is the same. You are the author. You get to decide what is in the file.\n\nStripping invisible characters does not defeat a real watermark either. What actually reads as machine-written is cadence, every sentence the same shape and length, and no character cleanup fixes that. This is about clean, honest text, not disguise.\n\nCall it text hygiene. Same spirit as spell-check, just for the characters you cannot see.\n\nEverything above is the whole point for most readers. If you want the mechanics, here they are.\n\nThe characters worth watching fall into a few buckets:\n\n`U+200B`\n\n), zero-width non-joiner (`U+200C`\n\n), zero-width joiner (`U+200D`\n\n), and the word joiner (`U+2060`\n\n). These take up no visible space at all, which is exactly what makes them easy to miss.`U+FEFF`\n\n). Frequently hitchhikes at the start of copied text.`U+00A0`\n\n) is the common one. There is also a whole family of unusual spaces (thin, hair, figure, and so on) in the `U+2000`\n\nto `U+200A`\n\nrange.`U+2018`\n\n, `U+2019`\n\n, `U+201C`\n\n, `U+201D`\n\n), plus the en dash (`U+2013`\n\n) and em dash (`U+2014`\n\n) that autoformatters love to insert.`U+E0000`\n\nto `U+E007F`\n\n). An obscure block that has become the vehicle for so-called ASCII smuggling, where readable-looking text hides an invisible payload.The cleaning logic is not complicated in spirit: strip the characters that should never be in plain text, normalize the ones that have an obvious plain equivalent, and leave everything legitimate untouched. The library exposes a few tiers so you can match how aggressive the cleaning is to where the text is going. Install it with `npm install ai-text-hygiene`\n\n, then:\n\n``` js\nimport { clean, stripInvisible, cleanConservative } from 'ai-text-hygiene';\n\n// Full house-style clean for prose: strips invisibles, folds curly\n// quotes to straight, em dash to a comma, ellipsis to three dots.\nclean('We \"delivered\" results — on time…');\n// => 'We \"delivered\" results, on time...'\n\n// Strip-only tier, safe for any language (no punctuation changes).\nconst zwsp = String.fromCharCode(0x200B); // a zero-width space, invisible in input\nstripInvisible('in' + zwsp + 'visible');\n// => 'invisible'\n\n// Length-stable tier for capped fields: 1:1 swaps, no growth.\ncleanConservative('curly \"quotes\" to straight');\n```\n\nThe important design choice is what you do *not* strip. Normalizing is a judgment call: turning a curly quote into a straight one is safe and almost always what you want in a form field, but you would not want to flatten legitimate content in a language that depends on characters an overeager filter might catch. That is why the strip-only tier is the one that is safe for any language, while the full clean targets English house style. The real work is in choosing the right set to remove versus the right set to normalize, and in doing it predictably every time.\n\nIn my project this lives in a single module (`text-hygiene-core`\n\n) so the same rules apply everywhere text leaves the app, and it is published on its own as an open-source library under the MIT license. If you want to read the actual code or drop it into your own tools, the repo is here:\n\nI did not set out to write a Unicode cleaner. I built [trajecktory](https://michaelinghilterra.com/Trajecktory), a tool to run my own job search like a pipeline, and text hygiene turned out to be one of those small, unglamorous problems that quietly matters. Every resume, every cover letter, every message that leaves the app should be clean, plain, and exactly what I wrote. Nothing hidden, nothing I cannot see.\n\nIf you have ever wondered why a form rejected text that looked perfectly fine, this is often the reason. Now you can see it, and clean it.\n\n*trajecktory is open source and still evolving. If this was useful, the code is on GitHub and I write about building it as I go.*", "url": "https://wpnews.pro/news/the-invisible-characters-hiding-in-your-ai-written-text", "canonical_source": "https://dev.to/michael_inghilterra/the-invisible-characters-hiding-in-your-ai-written-text-4kae", "published_at": "2026-08-16 17:44:45+00:00", "updated_at": "2026-08-16 18:12:36.656402+00:00", "lang": "en", "topics": ["artificial-intelligence", "developer-tools"], "entities": [], "alternates": {"html": "https://wpnews.pro/news/the-invisible-characters-hiding-in-your-ai-written-text", "markdown": "https://wpnews.pro/news/the-invisible-characters-hiding-in-your-ai-written-text.md", "text": "https://wpnews.pro/news/the-invisible-characters-hiding-in-your-ai-written-text.txt", "jsonld": "https://wpnews.pro/news/the-invisible-characters-hiding-in-your-ai-written-text.jsonld"}}