CLAUDE WATERMARK REMOVER · PRACTICAL TEST
Does successful JSON parsing mean the cleaned document is an object?
No. Our repaired 123 parses successfully as a number; null and an array also parse. Only the object control meets our explicit non-null, non-array object check. A successful parse does not enforce the receiving schema.
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 numeric document direct string / keep / invisible true | "123"U+0031 U+0032 U+200B U+0033 | "123"Removed 1 invisible character | {"accepted":false,"errorName":"SyntaxError"}{"accepted":true,"value":123,"rootType":"number","isArray":false,"isRecord":false} |
| Object document direct string / keep / invisible true | "{\"value\":123}"U+007B U+0022 U+0076 U+0061 U+006C U+0075 U+0065 U+0022 U+003A U+0031 U+0032 U+0033 U+007D | "{\"value\":123}"No selected invisible characters found | {"accepted":true,"value":{"value":123},"rootType":"object","isArray":false,"isRecord":true}{"accepted":true,"value":{"value":123},"rootType":"object","isArray":false,"isRecord":true} |
| Array document direct string / keep / invisible true | "[123]"U+005B U+0031 U+0032 U+0033 U+005D | "[123]"No selected invisible characters found | {"accepted":true,"value":[123],"rootType":"object","isArray":true,"isRecord":false}{"accepted":true,"value":[123],"rootType":"object","isArray":true,"isRecord":false} |
| Null document direct string / keep / invisible true | "null"U+006E U+0075 U+006C U+006C | "null"No selected invisible characters found | {"accepted":true,"value":null,"rootType":"object","isArray":false,"isRecord":false}{"accepted":true,"value":null,"rootType":"object","isArray":false,"isRecord":false} |
The parser and the record check answer different questions
The marked numeric document contains an actual U+200B between digits and initially raises SyntaxError. The selected cleanup removes that character and yields the text 123. JSON.parse now returns the number 123, while our isRecord field remains false. The object control produces a record containing a numeric value and passes both checks. The array control parses successfully but fails the explicit record check. The null control also parses successfully and fails that check, even though JavaScript reports its typeof as object. These four paired observations identify exactly what improved after cleanup: syntactic acceptance of the numeric document, without any conversion of its root into an object.
A root type requirement belongs to the receiving application
The observer deliberately distinguishes arrays and null from other object values instead of relying on typeof alone. It does not validate required properties, nested types, numeric ranges or a formal JSON Schema. Our earlier structural-whitespace guide explains whether a character may occur between JSON tokens; this experiment asks what a successfully parsed complete document represents. The plain array and null require no repair at all, yet remain unsuitable for the particular record requirement we chose. That requirement is an illustrative application contract, not a claim that arrays or primitive JSON roots are invalid JSON. Other destinations can intentionally accept them, and their own schema should decide the permitted result.
Retain the parsed value and then validate its contract
Keep the raw document, run the parser with an explicit error path, and inspect the actual root before accessing object properties. If the receiving endpoint requires a record, reject the three non-record outcomes here with a distinct reason rather than treating them as empty objects. Continue with the endpoint’s property and value checks after that first step. Our harness contacts no endpoint and therefore establishes no server acceptance, business validity or successful import. A cleaner status of one removed character describes the textual edit only. The downloadable rows retain both parser acceptance and the separate type fields so a repaired spelling cannot be mistaken for a completed schema validation.
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.parse 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.