CLAUDE WATERMARK REMOVER · PRACTICAL TEST
Can a text cleaner validate the original UTF-8 file bytes?
No. Our fatal decoder rejects byte 80 and truncated e282, while a default decoder replaces both. Valid UTF-8 for U+FFFD is accepted. Cleaning the hex labels changes none of those decisions.
Open the Claude text cleaner · Full measured data
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.
| Fixture and mode | Input string and code points | Output and cleaner status | Observed before / after |
|---|---|---|---|
| Invalid continuation byte direct string / keep / invisible true | "80"U+0038 U+0030 | "80"No selected invisible characters found | {"hex":"80","defaultText":"�","fatal":{"accepted":false,"errorName":"TypeError"}}{"hex":"80","defaultText":"�","fatal":{"accepted":false,"errorName":"TypeError"}} |
| Valid marker bytes direct string / keep / invisible true | "41e2808b42"U+0034 U+0031 U+0065 U+0032 U+0038 U+0030 U+0038 U+0062 U+0034 U+0032 | "41e2808b42"No selected invisible characters found | {"hex":"41e2808b42","defaultText":"AB","fatal":{"accepted":true,"text":"AB"}}{"hex":"41e2808b42","defaultText":"AB","fatal":{"accepted":true,"text":"AB"}} |
| Truncated multibyte sequence direct string / keep / invisible true | "e282"U+0065 U+0032 U+0038 U+0032 | "e282"No selected invisible characters found | {"hex":"e282","defaultText":"�","fatal":{"accepted":false,"errorName":"TypeError"}}{"hex":"e282","defaultText":"�","fatal":{"accepted":false,"errorName":"TypeError"}} |
| Literal replacement character direct string / keep / invisible true | "efbfbd"U+0065 U+0066 U+0062 U+0066 U+0062 U+0064 | "efbfbd"No selected invisible characters found | {"hex":"efbfbd","defaultText":"�","fatal":{"accepted":true,"text":"�"}}{"hex":"efbfbd","defaultText":"�","fatal":{"accepted":true,"text":"�"}} |
The same displayed symbol has different byte histories
We author four byte buffers using hexadecimal labels. The lone continuation byte 80 and unfinished sequence e282 each produce a replacement character with the default decoder. In fatal mode both throw TypeError. By contrast, efbfbd encodes a literal U+FFFD and is accepted by the fatal decoder, despite displaying the same symbol. The valid marked AB buffer is also accepted and contains U+200B in its decoded text. The table keeps the hex bytes, default result and fatal outcome together. These independent observations let us distinguish invalid encoding from a legitimate encoded replacement character without guessing from its appearance.
Hex labels are an explicit experiment boundary
The homepage receives the ASCII hex notation, not the byte buffer. Its output leaves that notation unchanged. Each observer then constructs the buffer from the exact notation and tests the two decoders independently. This is intentional: our string cleaner cannot validate incoming bytes it never receives. The earlier stream article uses valid bytes split between chunks; today we test complete, potentially invalid buffers with fatal mode. The older TextEncoder experiment starts with JavaScript surrogates and creates outgoing bytes. Neither answers whether these original incoming buffers satisfy UTF-8. No actual user file or Claude response is present in this matrix.
Retain bytes when encoding validity matters
For a file workflow that requires valid UTF-8, retain its original bytes and apply an explicit decoding policy before interpreting text. A decoded textarea value cannot reliably tell you whether its replacement character came from a decoding failure or was already present in a valid file. Our valid efbfbd control demonstrates that limitation directly. Do not re-encode displayed text and treat the new valid bytes as proof about the original file. This experiment does not inspect the homepage file picker, test every invalid sequence or recover intended characters. It provides four repeatable decoder outcomes, and leaves the separate decision about editing decoded formatting characters to the reader.
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.cjsReference and next check
WHATWG Encoding Standard 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.