Zerowidth CleanerAll measured guides

CLAUDE WATERMARK REMOVER · PRACTICAL TEST

Why does my cleaned é decode as i through Buffer ascii?

Our Latin1 byte E9 decodes as é with latin1 and i with ascii. Cleanup retains é. The ÿ control becomes code point 127 through ascii, showing a byte-decoding change independent of invisible-character deletion.

Tested October 23, 2026 · v24.19.0 · 4 measured runs

Open the Claude text cleaner · Full measured data

Code-point comparison for Marked accented text

Measured inputs and outputs

These are locally constructed test strings, not evidence that Claude inserts these characters. We executed the saved homepage script snapshot with a minimal DOM harness and compared exact strings. The invisible-checkbox state and dash mode appear in each row. The observations below test this page's specific question. Destination observations run independently on the exact input and cleaned strings in the recorded Node runtime. We make no detector-score or statistical-watermark removal claim.

Before and after observations; full code points and strings are in the JSON download.
Fixture and modeInput string and code pointsOutput and cleaner statusObserved before / after
Marked accented text
direct string / keep / invisible true
"é​"
U+00E9 U+200B
"é"
Removed 1 invisible character
{"latin1EncodedHex":"e90b","decodedLatin1":"é\u000b","decodedAscii":"i\u000b","asciiCodePoints":[105,11]}
{"latin1EncodedHex":"e9","decodedLatin1":"é","decodedAscii":"i","asciiCodePoints":[105]}
Accented text
direct string / keep / invisible true
"é"
U+00E9
"é"
No selected invisible characters found
{"latin1EncodedHex":"e9","decodedLatin1":"é","decodedAscii":"i","asciiCodePoints":[105]}
{"latin1EncodedHex":"e9","decodedLatin1":"é","decodedAscii":"i","asciiCodePoints":[105]}
High-bit code point
direct string / keep / invisible true
"ÿ"
U+00FF
"ÿ"
No selected invisible characters found
{"latin1EncodedHex":"ff","decodedLatin1":"ÿ","decodedAscii":"","asciiCodePoints":[127]}
{"latin1EncodedHex":"ff","decodedLatin1":"ÿ","decodedAscii":"","asciiCodePoints":[127]}
ASCII reference
direct string / keep / invisible true
"AB"
U+0041 U+0042
"AB"
No selected invisible characters found
{"latin1EncodedHex":"4142","decodedLatin1":"AB","decodedAscii":"AB","asciiCodePoints":[65,66]}
{"latin1EncodedHex":"4142","decodedLatin1":"AB","decodedAscii":"AB","asciiCodePoints":[65,66]}

The retained accent reaches two different decoders

The observer first generates Latin1 bytes from the exact string, then decodes the same bytes under two names. After cleanup, é is still the string sent to Buffer.from and its byte is E9. The Latin1 decoder returns é while the ASCII decoder returns i, recorded as code point 105. Thus the visible accent loss takes place after the cleaner, at decoding. Before cleanup the extra selected marker contributes byte 0B in this deliberately lossy encoding path; that byte disappears from the cleaned branch while the E9 disagreement remains.

Hex and decimal code points expose invisible output

Plain é reproduces the mismatch without a selected character. The ÿ control encodes as FF and ASCII decoding produces code point 127; its displayed glyph is not a reliable way to identify that result, so the record includes decimal code points. AB supplies an ASCII-only reference with bytes 4142 and identical decodes. Earlier Latin1 coverage measures loss when encoding a Unicode string; here the retained E9 and FF bytes already exist and the two decoders interpret them differently. No file, HTTP header or browser charset is consulted in this test.

Preserve bytes and label the conversion stage

When investigating an export discrepancy, keep the original Unicode value, generated hex and exact decoder name together. A cleaner status describing selected characters cannot certify that a later encoding roundtrip preserves every retained letter. The supplied reproducer uses Node Buffer behavior, not a browser TextDecoder with a similarly named label. It tests just four strings and does not recover information already discarded by encoding or high-bit clearing. These strings were authored for diagnosis. They do not show that Claude emitted any byte sequence, identify an author or measure removal of a statistical watermark.

Reproduce this test

Save reproduce.cjs and tested-app.js in the same folder. Run the command below with Node.js. The harness prints its runtime, script SHA-256 and every measured row. Compare those rows with the original record. Using a newer script or runtime creates a new experiment; retain the version information with your rerun.

node reproduce.cjs

Reference and next check

Node.js Buffer encodings provides the relevant primary definition. The table and fixture analysis are original measurements. For broader inspection, use our Unicode inspector. Read the scope distinction before interpreting cleanup as a watermark result.