Zerowidth CleanerAll measured guides

CLAUDE WATERMARK REMOVER · PRACTICAL TEST

Why does a missing value disappear from an object but become null in an array?

In our JSON.stringify test, undefined produces {} inside an object and [null] inside an array; at the root it returns undefined rather than JSON text. An explicit null stays present. Character cleanup does not choose a missing-value representation.

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

Open the Claude text cleaner · Full measured data

Code-point comparison for Marked missing lookup

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 missing lookup
direct string / keep / invisible true
"mi​ssing"
U+006D U+0069 U+200B U+0073 U+0073 U+0069 U+006E U+0067
"missing"
Removed 1 invisible character
{"ownProperty":false,"valueType":"undefined","isNull":false,"objectJson":"{}","arrayJson":"[null]","rootIsUndefined":true,"rootJson":null}
{"ownProperty":false,"valueType":"undefined","isNull":false,"objectJson":"{}","arrayJson":"[null]","rootIsUndefined":true,"rootJson":null}
Missing property
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
{"ownProperty":false,"valueType":"undefined","isNull":false,"objectJson":"{}","arrayJson":"[null]","rootIsUndefined":true,"rootJson":null}
{"ownProperty":false,"valueType":"undefined","isNull":false,"objectJson":"{}","arrayJson":"[null]","rootIsUndefined":true,"rootJson":null}
Null property
direct string / keep / invisible true
"nil"
U+006E U+0069 U+006C
"nil"
No selected invisible characters found
{"ownProperty":true,"valueType":"object","isNull":true,"objectJson":"{\"value\":null}","arrayJson":"[null]","rootIsUndefined":false,"rootJson":"null"}
{"ownProperty":true,"valueType":"object","isNull":true,"objectJson":"{\"value\":null}","arrayJson":"[null]","rootIsUndefined":false,"rootJson":"null"}
Present property
direct string / keep / invisible true
"present"
U+0070 U+0072 U+0065 U+0073 U+0065 U+006E U+0074
"present"
No selected invisible characters found
{"ownProperty":true,"valueType":"string","isNull":false,"objectJson":"{\"value\":\"AB\"}","arrayJson":"[\"AB\"]","rootIsUndefined":false,"rootJson":"\"AB\""}
{"ownProperty":true,"valueType":"string","isNull":false,"objectJson":"{\"value\":\"AB\"}","arrayJson":"[\"AB\"]","rootIsUndefined":false,"rootJson":"\"AB\""}

The same missing lookup has three serialization outcomes

We look up each supplied key in a small object whose only properties are nil with null and present with the string AB. Both the marked missing key and its cleaned spelling still identify an absent property. For their undefined result, the object wrapper serializes to {}, the array wrapper to [null], and the root serializer returns JavaScript undefined. Our rootIsUndefined flag records that last outcome directly; the adjacent rootJson null is only an explicit placeholder in the evidence record, not a claim that the root call returned the JSON text null. Cleaning the marked lookup changes its spelling but creates no property in the source object.

Absence and explicit null are distinguishable before export

The nil control is an own property, has value null and serializes with the object field retained. Its array output matches the missing lookup’s [null], demonstrating that those two original states are indistinguishable in that particular serialized array. The present control retains AB in every position. We record Object.hasOwn, typeof and an explicit null flag before serialization so this loss is inspectable. No reviver, replacer, toJSON hook or global modification participates. Earlier guides cover those separate transformations and numeric export issues. This test concerns ordinary undefined values obtained from a missing lookup, not a claim that JSON has an undefined literal or that every missing database value follows this convention.

Decide what the receiving schema needs to preserve

If absence and explicit null have different meanings, choose a representation that carries that distinction and check it on the receiving side. Replacing undefined with null may preserve an object field while intentionally discarding its original distinction; it is not automatic recovery. The minimal observer here only records existing default serializer behavior and does not recommend a sentinel string or modify the object. Do not pass a root undefined result to code expecting JSON text without handling that case. Retain the lookup-presence evidence alongside any export when investigating a disappearing field. The cleaner’s removal count cannot explain serializer omissions that also occur in an unmarked control.

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.