Zerowidth CleanerAll measured guides

CLAUDE WATERMARK REMOVER · PRACTICAL TEST

Why does Number.isFinite reject the cleaned string 12?

Our cleaned 12 remains a string: Number.isFinite(text) is false while global isFinite(text) is true. Number.isFinite(Number(text)) is true, but the empty-string control also converts to zero. Validate required text before applying numeric checks.

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

Open the Claude text cleaner · Full measured data

Code-point comparison for Marked number

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 number
direct string / keep / invisible true
"1​2"
U+0031 U+200B U+0032
"12"
Removed 1 invisible character
{"inputType":"string","globalFinite":false,"strictStringFinite":false,"converted":"NaN","strictConvertedFinite":false}
{"inputType":"string","globalFinite":true,"strictStringFinite":false,"converted":"12","strictConvertedFinite":true}
Plain number
direct string / keep / invisible true
"12"
U+0031 U+0032
"12"
No selected invisible characters found
{"inputType":"string","globalFinite":true,"strictStringFinite":false,"converted":"12","strictConvertedFinite":true}
{"inputType":"string","globalFinite":true,"strictStringFinite":false,"converted":"12","strictConvertedFinite":true}
Empty string
direct string / keep / invisible true
""
""
No selected invisible characters found
{"inputType":"string","globalFinite":true,"strictStringFinite":false,"converted":"0","strictConvertedFinite":true}
{"inputType":"string","globalFinite":true,"strictStringFinite":false,"converted":"0","strictConvertedFinite":true}
Infinity spelling
direct string / keep / invisible true
"Infinity"
U+0049 U+006E U+0066 U+0069 U+006E U+0069 U+0074 U+0079
"Infinity"
No selected invisible characters found
{"inputType":"string","globalFinite":false,"strictStringFinite":false,"converted":"Infinity","strictConvertedFinite":false}
{"inputType":"string","globalFinite":false,"strictStringFinite":false,"converted":"Infinity","strictConvertedFinite":false}

Three checks answer different questions on one string

The marked numeric source initially converts to NaN, and all three finiteness branches return false. Cleanup produces the text 12. Global isFinite now returns true, Number.isFinite on the string remains false, and Number.isFinite on the explicitly converted number returns true. The inputType field says string in both stages. That field prevents the successful cleanup from being mistaken for a type conversion. The earlier numeric-conversion guide measures what Number returns; this comparison isolates the predicate a validator applies and whether that predicate converts its own argument.

The empty control makes coercion policy visible

Plain 12 reproduces the predicate disagreement without any selected marker. Empty text is especially useful: global isFinite returns true, its explicit Number result is zero, and strict finiteness on that converted value is true. Strict finiteness on the original empty string remains false. Infinity supplies a nonfinite spelling that all three checks reject, although the converted diagnostic preserves the word Infinity rather than reporting NaN. No field is silently omitted in the JSON data; numeric diagnostics are deliberately strings so their exact meanings survive serialization of the record.

Required input and finite output are separate validation steps

A form that requires a number should decide its accepted text grammar and empty-input policy before interpreting the converted result. Passing the converted-zero predicate does not prove that a person supplied zero. This matrix does not implement locale parsing, a spreadsheet importer, range limits or a complete validation library. It compares four strings with fixed built-in calls in the recorded runtime. Cleanup deletes its selected marker and leaves every result a string. No fixture comes from a Claude conversation, and none measures authorship, detector behavior or an embedded statistical watermark.

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 Number.isFinite 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.