Build1 distinct publisher3 min readUpdated
A team that sells precision guardrails found its own browser pages calling JSON.parse directly, rounding a snowflake ID by 1,788 with no error. The server path was safe. The client path was not.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
A team that builds JSON repair tooling ran `{"id": 22233344455566677788}` through its own browser-based tool and got back `{"id": 22233344455566676000}` with no error and no warning, presented as a successful repair [1]. The number was a made-up snowflake ID, the shape of thing that serves as a primary key in a distributed system [2], which means the failure mode is not cosmetic: it is a silently rewritten row identifier.
The mechanism is boring and well documented. JSON has one numeric type, and JavaScript resolves every number to an IEEE 754 double once `JSON.parse` touches it [3]. Doubles hold integers exactly up to `Number.MAX_SAFE_INTEGER`, 2^53 - 1, which is 16 digits; beyond that the value rounds to the nearest representable double with no exception thrown and no flag set [4]. The test ID is 20 digits, four digits past the exact range [2] and roughly 2,470 times `MAX_SAFE_INTEGER` [3]. The output was 1,788 short of the input, with the last four digits flattened to zeros [1]. There is no recovery step afterwards, because the information needed to reconstruct the original is gone; the choices are to catch it before parsing and refuse, or let it through [5].
The organisational half is the more useful part. According to the dev.to writeup, the team's API already had the right guard: a shared core module scanned raw request text for numbers that would lose precision and rejected with a 422 before any of four processing engines (clean, schema-validate, transform, AI-repair) parsed anything [9]. Three of those tools also ship browser-only pages, and those pages called `JSON.parse` directly instead of the shared guard [10]. Nobody filed a bug. The team found it by walking page by page and feeding oversized numbers into everything it ships, and three of four browser pages let the value through [11]. The counts in the post do not quite reconcile, three tools with browser versions against three of four failing pages, which is worth flagging if you read this as an audit rather than a confession [11].
One case is worth copying into your own test plan. The CSV-to-JSON converter submits the CSV as a single JSON string field, so a scan of the outer request sees no bare numbers at all; the digits stay inside a string until the CSV rows are parsed, which is exactly where the rounding happened [12]. A guard at the front door does nothing if text becomes numbers somewhere deeper in.
The team also reports it had originally made the large-integer check non-blocking on purpose, logging rather than rejecting, on the reasoning that some systems legitimately transmit 64-bit keys and snowflake IDs as raw JSON numbers [13]. It later concluded that warn-only does not prevent corruption, it only puts a log line next to the corruption, since no code path repairs an oversized integer without first losing it [14]. The supplied text cuts off mid-sentence as the author describes checking their own traffic, so the traffic finding itself is not available [15].
None of this is novel. Twitter has shipped a numeric `id` and a string `id_str` in the same response for this reason [6], Stripe represents money as integer cents [7], and pandas has open GitHub issues dating to 2017 about `to_json()` mangling large integers, still unresolved [8].
What to watch: whether your own ingest rejects oversized integers or merely logs them [14], whether your client-side and edge paths share the server's validation code or reimplement it [10], and whether any payload arrives with numbers wrapped inside string fields that your outer scan cannot see [12]. When you buy an API, ask for string-typed identifiers [6].
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
The team concluded that the warn-only compromise did not hold up: no code path fixes an oversized integer without first losing precision, so a warn-only mode does not prevent corruption, it only adds a log line next to the corruption.
The team ran {"id": 22233344455566677788} through its own JSON repair tool in the browser and it returned {"id": 22233344455566676000}, with no error and no warning, presented as a successful repair.
The number used in the test is a made-up snowflake ID, the kind of value seen as a primary key in a distributed system.
JSON does not distinguish integers from floats, it has only "number"; in JavaScript every number becomes an IEEE 754 double-precision float once JSON.parse processes it.
Doubles represent integers exactly up to Number.MAX_SAFE_INTEGER (2^53 - 1, which is 16 digits); past that the value is silently rounded to the nearest representable double, with no exception thrown and no flag set.
Once a value has passed through JSON.parse and become a JS Number the original precision is gone and no repair step can reconstruct it; the only options are to catch it before parsing and refuse to proceed, or let it happen.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Checkable mechanism, single self-reported source
The core technical mechanism is strong: the stated behaviour of JSON's single number type, IEEE 754 doubles and Number.MAX_SAFE_INTEGER is verifiable from language semantics, the corrupted input and output literals are reproduced exactly, and a curl call plus the resulting 422 payload are shown. What limits the score is provenance — one publisher, one vendor author, no independent reproduction, no post-fix test artifacts, and one cited third-party claim (pandas to_json()) with no locators at all.
Vendor's own tools only; no external uptake evidence
The only adoption facts supplied are internal to the vendor: a shipped client-side check across its own browser tools, and an explicit statement that its traffic review found no real callers depending on the prior behaviour. No customers, download counts, downstream integrations, or third-party deployments appear. The referenced Twitter, Stripe and pandas practices show the underlying problem is widespread but say nothing about adoption of this vendor's approach.
Broadly aligned, mild vendor framing
Claims track the evidence closely and the piece is mostly self-critical: it discloses that three of four of its own browser pages failed, that the guard was deliberately warn-only, and that the failure was found by manual audit rather than reported. Slight overstatement comes from the generalising 'most tools quietly hope you never hit' framing built partly on the unsourced pandas assertion, and from the closing product plug and API sample, which convert a post-mortem into a capability pitch. One ledger claim of source truncation overstated a limitation that the supplied body does not exhibit.
Vendor authoring about its own product, with promotion
The author is the operator of the tool under discussion, the post closes with the product domain and a runnable API example including an API-key header, and the disclosure doubles as a trust-building argument for a service whose pitch is 'we don't ship plausible-looking but wrong results'. The counterweight is real: admitting that three of four shipped browser pages corrupted data cuts against short-term marketing interest, so the incentive is promotional but not concealing.
Moderate: verifiable mechanism, unverifiable specifics
Confidence is held down by single-source, single-publisher provenance and by self-reported audit and remediation details that no external party confirms. It is held up by the fact that the central technical claim can be checked against language semantics independently of the author, and by the specificity of the reproduced literals, digit limits and error payload. One ledger claim about the source was contradicted on inspection, which was resolvable directly from the supplied text.
build
The money bug that survives your migration to decimals1 distinct publisher
build
Allow-list the closed set, block-list the open one: 193 thin geo pages, one gate1 distinct publisher
build
Before you spend quota on an agent skill, make it pass an eval harness1 distinct publisher
build
Three API calls, no rollback: the phone numbers your carrier bills and your database never saw1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 20, 2026