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 {}.
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 |
|---|---|---|---|
| Marked whitelist key direct string / keep / invisible true | "name"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 | "name"U+006E U+0061 U+200D U+006D U+0065 | "name"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.cjsReference 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.