You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Fleet Sweeps: sweep ids emitted as JSON numbers exceed JavaScript's safe range — the web drill-down fetches a mangled id and finds nothing #3487
Sweep ids are emitted as JSON numbers in every fleet-sweep payload, and a sweep id is a tick-scale value (~6.4e17) — roughly 70x past Number.MAX_SAFE_INTEGER. Any JavaScript consumer's JSON.parse silently rounds it: measured live on a production store during the .444 post-install review, the store's 639251940075451830 parses to 639251940075451800. The Fleet Sweeps page then interpolates the mangled id into apiGet("/api/sweeps/" + selectedSweepId), the {id:long} route parses it as a valid-but-wrong long, and the detail pane answers "no sweep with id … exists - pruned by retention, or never recorded" for a sweep sitting right there in the timeline.
Verified both directions live: the fetch with the true id (extracted from the raw response text, bypassing the parse) returns the full detail; the fetch with the parsed id returns the empty-status message.
Why the drill-down is broken essentially always, and why dogfooding missed it
The rounding granularity at this magnitude is ~128 ticks, so effectively every sweep id is unrepresentable — adjacent sweeps sit ~3.6e13 ticks apart, so there are no cross-sweep collisions, just wrong-id misses. The page loads green because the detail pane defaults to /api/sweeps/latest (no id round-trip), and on day-one stores with a single sweep there was no historical row to click. The first operator to click yesterday's sweep gets a confident "never recorded" about a document the timeline is displaying.
The irony that makes this worth a written lesson: the input side was designed against exactly this — get_sweep_reports takes sweep_id as a string with exact-parse-or-refuse, and the PR that shipped it says why ("avoids the JSON-double round-trip issue for tick-scale ids"). The output side then handed every consumer a value that had already been through the double.
Fix shape
Emit tick-scale ids as JSON strings at the presentation layer, both surfaces (/api/sweeps* and get_sweep_reports ride the same builders): sweep_id and previous_sweep_id on timeline rows, detail nodes, and the watch-item payload if present. The embedded stored report document also carries both ids as numbers — stored docs are immutable, so convert those two fields in the freshly parsed embed at render, the #3478 arm-B precedent (a render rule, never a data rewrite).
sweeps.js needs no functional change: "/api/sweeps/" + id concatenates a string fine, the active comparison compares like with like, and previous_sweep_id == null is unaffected — but verify against the source pins.
Tests: update the shape pins that expect numeric ids; add the pin that every tick-scale id in a serialized sweep payload is a JSON string (the JS-safe-integer argument stated at the pin); both surfaces covered via the shared-builder pin; the embed-conversion arm gets the legacy-doc treatment (#3478's fixture precedent).
Found on 3.7.0-nightly.20260916.444 during the post-install review pass, all three production stores. Fix lane is dispatched (this seat's feature, this seat's find).
Activity
Spell tick-scale sweep ids as JSON strings on the wire, both surfaces…
erikdarlingdata commentedon Sep 16, 2026
Closed by #3488 (merged to dev).