For programmers

Invisible characters in code: the bug you can't see

Two strings that look identical refuse to match. A validator rejects a valid ID. A copied snippet quietly breaks a build. The culprit is often an invisible character — and you can't fix what you can't see.

By NoAtMark · Published Aug 12, 2026 · 9 min read

A debugging story

You paste an API key from a dashboard into a config file. The key "looks" right. Every integration returns 401. You compare the key against the dashboard character-by-character — identical. Then you hexdump it and find e2 80 8b (UTF-8 for U+200B) hiding inside. That one invisible byte is why nothing authenticates.

This isn't exotic. Zero-width characters get into code through the same channels every developer uses: copying from web pages, AI assistants, docs, chat, and even email. The characters are legitimate Unicode; their unintentional presence in identifiers, strings, and config is the bug.

How they get in

Invisible Unicode characters — zero-width space (U+200B), zero-width joiner (U+200D), BOM (U+FEFF), soft hyphen (U+00AD), direction marks (U+200E/U+200F) — render as nothing but count as characters. When you copy code from a source that contains them, your editor often displays nothing and your toolchain counts the invisible byte.

The symptoms

1. String matching fails

// This looks like it should be true:
if ("user" === "user") { /* never runs */ }
// One of these strings contains a hidden U+200B.

2. Validation rejects valid input

IDs, keys, phone numbers, and email addresses with an invisible byte fail regex or length checks even though they "look" valid. The classic case: a 16-character key that's actually 17 bytes.

3. CSV and JSON break

Invisible characters in a field can split a record, produce an unexpected column, or make two "identical" rows unequal. (See the data article for the analyst's view.)

4. Security: hidden injection and Trojan-Source

Attackers can abuse invisible and bidirectional characters to hide malicious content. The Trojan-Source research (Boucher & Anderson, 2021) showed how invisible bidi controls and zero-width characters can make code appear to do one thing while the compiler reads another. This class of issue is why security guidance — from OWASP to CWE — warns about ambiguous Unicode in source.

How to find and fix it

Detect it first

Because the characters are invisible, you need a scanner. Paste the suspicious text (or a whole file) into the file cleaner. It scans first and reports every invisible character by type and count — before it touches anything. For quick pastes, the invisible character remover works on any text.

Then clean deliberately

Only after you've seen the report should you clean. The file cleaner strips invisible characters on your command and tells you how many it removed — so you always know what changed.

Preventing it in your workflow

  • Clean AI-generated code before committing. Copying code out of ChatGPT or Claude is a common source. A one-pass clean removes the risk.
  • Scan untrusted input. Anything you paste into a prompt, a database, or a config file from an external source should pass a hidden-text scan.
  • Automate the habit. The NoAtMark browser extension strips invisible characters automatically when you copy — or use the VS Code extension to clean a selection directly in your editor (Ctrl+Alt+Shift+C).
  • Add a CI guard. For teams, the text hygiene API can flag invisible characters in commits before they merge.

Real-world caveats

  • Some legitimate uses of zero-width characters exist (e.g., in text layout or emoji sequences). The file cleaner removes them from code and data where they're almost certainly unintended — but always review the scan report first.
  • Tools that claim to "remove AI watermarks" are a different category and, for statistical watermarks, can't work without the provider's key. Cleaning invisible characters is well-defined; that is not.

Frequently asked questions

Can I see invisible characters in my editor?

Yes, most editors have a "show whitespace" or "show invisible" toggle, and some linters flag zero-width characters. But it's easy to miss. A dedicated scan is more reliable.

Is this a security vulnerability by itself?

Invisible characters aren't inherently a vulnerability, but they can enable or obscure injection (including Trojan-Source-style bidi attacks), and they cause real availability bugs (matching/validation failures). Treat them as a code-hygiene and security-hygiene issue.

Does cleaning change my code?

No. Cleaning removes invisible characters only — identifiers, strings, and structure are unchanged. The scan report tells you exactly what was removed.

References & further reading

NoAtMark logo
The NoAtMark Team

NoAtMark is an independent project focused on text hygiene for the AI age. This article is written and fact-checked by the team; sources are linked under References. Every tool mentioned is free, private, and runs in your browser. About us →

Stop debugging invisible bytes

Add a 10-second scan to your copy-paste habit. The tools are free, private, and run entirely in your browser.

Clean a file →