Zerowidth CleanerAll measured guides

CLAUDE WATERMARK REMOVER · PRACTICAL TEST

Why does TextDecoder reject an unknown label instead of using UTF-8?

Our unknown and empty labels both raise RangeError. The marked utf-8 label becomes accepted only after its selected marker is removed. Decoder construction validates the supplied label before our fixed AB byte payload is decoded.

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

Open the Claude text cleaner · Full measured data

Code-point comparison for Marked supported label

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 supported label
direct string / keep / invisible true
"ut​f-8"
U+0075 U+0074 U+200B U+0066 U+002D U+0038
"utf-8"
Removed 1 invisible character
{"error":"RangeError"}
{"encoding":"utf-8","value":"AB"}
Supported label
direct string / keep / invisible true
"utf-8"
U+0075 U+0074 U+0066 U+002D U+0038
"utf-8"
No selected invisible characters found
{"encoding":"utf-8","value":"AB"}
{"encoding":"utf-8","value":"AB"}
Unknown label
direct string / keep / invisible true
"not-an-encoding"
U+006E U+006F U+0074 U+002D U+0061 U+006E U+002D U+0065 U+006E U+0063 U+006F U+0064 U+0069 U+006E U+0067
"not-an-encoding"
No selected invisible characters found
{"error":"RangeError"}
{"error":"RangeError"}
Empty label
direct string / keep / invisible true
""
""
No selected invisible characters found
{"error":"RangeError"}
{"error":"RangeError"}

A fixed payload isolates the label failure

Every successful branch decodes the same two bytes 41 and 42. The marked utf-8 label initially fails during TextDecoder construction with RangeError. After cleanup its spelling is utf-8, the resolved encoding field is utf-8 and the decoded value is AB. The successful plain reference produces the same fields. Because the payload never varies, an invalid UTF-8 byte sequence cannot explain the first error. This is a constructor configuration question, separate from the fatal-decoder guide that deliberately changes incoming bytes.

An empty supplied label differs from an omitted argument

The explicit empty string raises RangeError before and after cleanup in this matrix. We do not omit the constructor argument in that branch, so it should not be described as a test of the default argument. The not-an-encoding control also fails throughout and remains unchanged by the homepage. Those controls establish that selected-character removal does not invent a supported label or silently choose a fallback. The earlier label-alias guide tests an accepted name resolving to another encoding; these controls test rejection before any decoding result exists.

Keep rejection distinct from empty decoded content

A destination should report its actual label error rather than turning it into an empty decoded string or claiming successful UTF-8 fallback. If an application intentionally supplies a default, it should retain the original label and make that policy explicit. Our observer defines no fallback and reads no user files, so its AB output is only a fixed local control. Four labels in the recorded Node runtime bound the experiment; support in another environment requires its own check. No fixture is a Claude output sample, and successful configuration says nothing about authorship or statistical watermark removal.

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

WHATWG TextDecoder constructor 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.