Zerowidth CleanerAll measured guides

CLAUDE WATERMARK REMOVER · PRACTICAL TEST

Why does ?? keep an empty cleaned string instead of using my fallback?

Our marker-only input becomes empty text. The nullish operator and destructuring default preserve that empty string; logical OR selects the fallback. Decide whether your fallback means missing data or empty content.

Tested October 26, 2026 · v24.22.1 · 4 measured runs

Open the Claude text cleaner · Full measured data

Code-point comparison for Marker only

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
Marker only
direct string / keep / invisible true
"​"
U+200B
""
Removed 1 invisible character
{"nullish":"​","logicalOr":"​","destructured":"​","missingDefault":"fallback","length":1}
{"nullish":"","logicalOr":"fallback","destructured":"","missingDefault":"fallback","length":0}
Plain text
direct string / keep / invisible true
"AB"
U+0041 U+0042
"AB"
No selected invisible characters found
{"nullish":"AB","logicalOr":"AB","destructured":"AB","missingDefault":"fallback","length":2}
{"nullish":"AB","logicalOr":"AB","destructured":"AB","missingDefault":"fallback","length":2}
Empty string
direct string / keep / invisible true
""
""
No selected invisible characters found
{"nullish":"","logicalOr":"fallback","destructured":"","missingDefault":"fallback","length":0}
{"nullish":"","logicalOr":"fallback","destructured":"","missingDefault":"fallback","length":0}
Zero spelling
direct string / keep / invisible true
"0"
U+0030
"0"
No selected invisible characters found
{"nullish":"0","logicalOr":"0","destructured":"0","missingDefault":"fallback","length":1}
{"nullish":"0","logicalOr":"0","destructured":"0","missingDefault":"fallback","length":1}

The deletion exposes three different default policies

The first fixture contains exactly one U+200B, so its original string length is one. Before cleanup both fallback operators return that string. After deletion the recorded length is zero: nullish coalescing returns empty text, logical OR returns fallback, and destructuring the supplied text property also returns empty text. The separate missing-property control returns fallback at both stages. Those four observations identify the decision boundary without relying on how the invisible input looks in a form. The product supplied a string successfully; the consuming expression decides which kind of absence matters.

Zero spelling is content in these controls

The ordinary AB reference survives every expression unchanged. The explicit empty-string reference reproduces the cleaned first fixture even when the cleaner finds nothing. The zero-spelling reference stays the one-character string 0 under both operators, rather than selecting fallback. We do not supply numeric zero, false or null as the observer input. This matters because a configuration field read as text has different truthiness from a converted numeric value. The missing-default comparison deliberately constructs an object with no text property, making that separate source of a default observable.

Name the state that should activate a replacement

If empty text is a meaningful result, replacing it with a default may discard a deliberate deletion. If a destination requires visible content, preserving empty text may instead require an explicit validation error. Choose the policy before applying a fallback and retain the original input alongside the cleaned value. Destructuring defaults are not an empty-string validator. The narrow function in the download demonstrates only a missing property and a present string; it does not define how your application should handle explicit null, whitespace-only values or non-string records.

The operators do not inspect provenance

The actual homepage callback removes its selected marker before the observer evaluates the fallback expressions. It does not insert fallback text itself. Every string and object in this page is locally authored, with no imported conversation or external form submission. Earlier flag coverage asks what text true and false mean; this page asks when a replacement value is chosen. The two questions need separate contracts. An empty result and a chosen default provide no evidence of Claude authorship, statistical marking or detector behavior. Rerun the exact expressions when changing the destination data type.

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 coalesce expression 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.