Zerowidth CleanerAll measured guides

CLAUDE WATERMARK REMOVER · PRACTICAL TEST

Why can JSON.stringify return an empty object for a marked key?

Our object has name, but a replacer-array entry na + U+200B + me does not select it. Cleaning that whitelist entry produces name and serializes the Ada field; unknown entries still yield {}.

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

Open the Claude text cleaner · Full measured data

Code-point comparison for Marked whitelist key

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 whitelist key
direct string / keep / invisible true
"na​me"
U+006E U+0061 U+200B U+006D U+0065
"name"
Removed 1 invisible character
{"serialized":"{}"}
{"serialized":"{\"name\":\"Ada\"}"}
Plain whitelist key
direct string / keep / invisible true
"name"
U+006E U+0061 U+006D U+0065
"name"
No selected invisible characters found
{"serialized":"{\"name\":\"Ada\"}"}
{"serialized":"{\"name\":\"Ada\"}"}
Retained joiner
direct string / keep / invisible true
"na‍me"
U+006E U+0061 U+200D U+006D U+0065
"na‍me"
No selected invisible characters found
{"serialized":"{}"}
{"serialized":"{}"}
Unknown key
direct string / keep / invisible true
"missing"
U+006D U+0069 U+0073 U+0073 U+0069 U+006E U+0067
"missing"
No selected invisible characters found
{"serialized":"{}"}
{"serialized":"{}"}

The edited text controls which field is exported

The object stays fixed as a name field containing Ada and a role field containing editor. Only the single string inside the replacer array varies. In the first row, its embedded U+200B prevents it from selecting name, so the exported document is the valid JSON object {}. After deletion, the entry matches name and the serializer emits the Ada field. The plain reference selects that field at both stages. The retained joiner and the genuinely missing key select neither field. Role is absent in every output because no fixture includes it in the whitelist. An empty object is therefore a successful serialization with a selection mismatch, not a syntax error.

Property selection differs from cleaning JSON source

We clean the whitelist entry before passing it to JSON.stringify. We do not clean the object, mutate its keys, parse malformed JSON or rewrite serialized bytes. The existing serialization guide measures characters carried inside string values; this matrix measures an auxiliary argument that determines which object properties reach the output. The earlier collision page also has a different trigger because no two object keys are merged here. The local object uses invented public labels only. The cleaner has no knowledge of a serializer whitelist and cannot infer whether adding a newly selected field is the intended export behavior.

Validate the requested export fields explicitly

Keep the original selection list and compare each entry with the object schema before serialization. Inspect the complete exported object after a targeted edit rather than treating valid JSON as proof that the right fields were included. If the whitelist is an intentional boundary, verify any newly selected field against that boundary before accepting the result. These fixtures test only one string entry and a two-property plain object. They do not cover nested selection, getters, toJSON methods, callback replacers or sensitive records. The downloads permit exact reruns without providing private data, and the field-selection outcome remains distinct from watermark detection.

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 JSON.stringify 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.