CLAUDE WATERMARK REMOVER · PRACTICAL TEST
Why does JSON still fail after invisible cleanup?
Our parser accepts JSON after removing a literal U+200B outside a string, but still rejects retained NBSP and NUL. A clean status does not validate JSON grammar.
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. File API and event-lifecycle tests include an additional stage described in the analysis. 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 |
|---|---|---|---|
| Selected character before key direct string / keep / invisible true | "{\"x\":1}"U+007B U+200B U+0022 U+0078 U+0022 U+003A U+0031 U+007D | "{\"x\":1}"Removed 1 invisible character | {"valid":false,"errorName":"SyntaxError"}{"valid":true,"value":{"x":1}} |
| NBSP before key direct string / keep / invisible true | "{ \"x\":1}"U+007B U+00A0 U+0022 U+0078 U+0022 U+003A U+0031 U+007D | "{ \"x\":1}"No selected invisible characters found | {"valid":false,"errorName":"SyntaxError"}{"valid":false,"errorName":"SyntaxError"} |
| NUL before key direct string / keep / invisible true | "{\u0000\"x\":1}"U+007B U+0000 U+0022 U+0078 U+0022 U+003A U+0031 U+007D | "{\u0000\"x\":1}"No selected invisible characters found | {"valid":false,"errorName":"SyntaxError"}{"valid":false,"errorName":"SyntaxError"} |
| Allowed tab direct string / keep / invisible true | "{\t\"x\":1}"U+007B U+0009 U+0022 U+0078 U+0022 U+003A U+0031 U+007D | "{\t\"x\":1}"No selected invisible characters found | {"valid":true,"value":{"x":1}}{"valid":true,"value":{"x":1}} |
Whitespace is part of the grammar
Our fixture begins with an opening brace and places one specific character before the quoted key x. The selected U+200B case fails JSON.parse before cleanup and parses afterward. NBSP and NUL remain in their inputs, and both still fail. The tab reference parses at both stages. These are structural positions, outside quoted values. The result is therefore about token separation, not an invisible character inside a key or a Unicode escape decoded into a string. The observer saves success and the error class rather than treating runtime error wording as a stable diagnostic.
Removal and validation answer different questions
RFC 8259 defines a narrow set of whitespace characters around JSON structural tokens. A character that looks blank in an editor is not automatically in that set. The homepage neither parses JSON nor reports the source offset of a syntax failure. Its no-findings message means no selected removal occurred under the settings shown in our record. It does not establish a valid request body. These four authored fixtures were measured with the recorded Node runtime; no CMS importer, database endpoint or Claude response was used to produce the examples.
Repair the rejected token deliberately
Save the complete original response and the parser error before editing a working copy. Determine whether the problem lies outside a string, inside a value or in a byte-decoding stage. For a confirmed unwanted structural character, make a targeted repair and run the same destination parser again. Do not delete spaces globally: spaces inside strings may be meaningful data. An accepted parse only establishes this grammar check; a schema and application rules may still reject the value. Keep those checks separate from the cleaner removal count and from any claim about authorship.
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
JSON grammar 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.