Zerowidth CleanerAll measured guides

CLAUDE WATERMARK REMOVER · PRACTICAL TEST

Can cleanup fix encodeURIComponent errors from a lone surrogate?

No in our fixtures. A lone UTF-16 surrogate remains and encodeURIComponent still throws URIError. Removing an adjacent U+200B does not repair the malformed string.

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

Open the Claude text cleaner · Full measured data

Code-point comparison for Lone high surrogate

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. File API and event-lifecycle tests include an additional stage described in the analysis. 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
Lone high surrogate
direct string / keep / invisible true
"A\ud800B"
U+0041 U+D800 U+0042
"A\ud800B"
No selected invisible characters found
{"accepted":false,"errorName":"URIError"}
{"accepted":false,"errorName":"URIError"}
Lone low surrogate
direct string / keep / invisible true
"A\udc00B"
U+0041 U+DC00 U+0042
"A\udc00B"
No selected invisible characters found
{"accepted":false,"errorName":"URIError"}
{"accepted":false,"errorName":"URIError"}
Lone surrogate plus marker
direct string / keep / invisible true
"A\ud800​B"
U+0041 U+D800 U+200B U+0042
"A\ud800B"
Removed 1 invisible character
{"accepted":false,"errorName":"URIError"}
{"accepted":false,"errorName":"URIError"}
Valid emoji pair
direct string / keep / invisible true
"A😀B"
U+0041 U+1F600 U+0042
"A😀B"
No selected invisible characters found
{"encoded":"A%F0%9F%98%80B","accepted":true}
{"encoded":"A%F0%9F%98%80B","accepted":true}

A code unit can be left without its pair

The first two fixtures explicitly place an unpaired high or low UTF-16 surrogate between A and B. Both throw URIError when passed to encodeURIComponent before and after cleanup. The mixed fixture loses U+200B but retains the unpaired high surrogate, so encoding still fails. The emoji reference contains a valid surrogate pair and encodes successfully at both stages. JSON string representations in the table preserve the escaped unpaired units rather than relying on a replacement glyph drawn by the page font. The record includes the exact input and output strings.

This is an encoding operation, not URL parsing

The observer applies encodeURIComponent to a component string. It does not parse an existing URL or percent-decode a path. The ECMAScript URI algorithm specifies behavior for malformed surrogate sequences, while the homepage deletion map contains no surrogate repair rule. We construct the cases in JavaScript to make those units explicit; ordinary text entry or file decoding may already replace malformed data before it reaches the cleaner. The experiment does not establish how such data originated in a real document, and it does not demonstrate a corrupted Claude response or a network failure.

Choose an explicit malformed-data policy

When a component encoder throws, preserve the original representation and inspect UTF-16 units before changing them. Locate the stage that created an unmatched surrogate and determine whether the upstream data can be repaired from its original bytes. If the application permits replacement, apply a documented well-formed-string policy and record the resulting loss of information. Do not treat deletion of another selected character as validation of the component. Rerun the intended encoder and verify the resulting destination value. Successful encoding checks that operation only; it does not establish semantic correctness or the safety of a URL destination.

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

ECMAScript URI handling 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.