Severity: P0. Reviewed at 82b715c. A conforming server can silently corrupt a value on the way out, and the conformance suite cannot catch it.
The hole
S5 defines the tagged-value encoding ({"$type":"bigint","$value":"<digits>"}) and puts exactly one obligation on the server: "Servers MUST accept the registered types" (SPEC.md:97). That is inbound only.
On the response side, S6.1 (SPEC.md:118) says row values "use the same JSON / tagged-value encoding as section 5." That names an encoding. It does not oblige anyone to emit it.
So a conforming server may return a stored SQLite INTEGER above 2^53 as a bare JSON number, and a JavaScript client rounds it. No rule is broken.
Why the conformance suite cannot catch it
P-5 roundtrips a bigint the client sent. A server that echoes what it was handed passes P-5 while still rounding every large value that was already in the table. The test needs to read a large integer the client never sent -- insert via literal SQL text, then SELECT it back.
Why a spec edit alone does not close it
This is the part that matters for tracking. encodeValue in both Cloudflare examples keys on the JS runtime type the driver handed back:
typeof value === "bigint"
By the time encodeValue sees a number, the driver has already rounded it -- the original 64-bit value is gone and is not recoverable at the encoding layer. So the fix is spec text PLUS driver configuration (D1/DO must be asked for bigints rather than numbers where the API allows it).
Do not let this issue be closed by an implementation that still loses the value. That is the specific failure mode worth guarding against here.
Proposed resolution
- S6.1: make emission normative -- a server MUST emit the tagged form for values outside the JSON-safe range, not merely reference the S5 encoding.
- Same treatment for BLOB values on the response side.
- Add a conformance case that inserts a large integer as SQL literal text and asserts the tagged form comes back.
Acceptance
Related: lastInsertId is the same data-loss class, filed separately.
Origin: codex spec review; source-level sharpening (the encodeValue recovery point) by smugglr.
Severity: P0. Reviewed at 82b715c. A conforming server can silently corrupt a value on the way out, and the conformance suite cannot catch it.
The hole
S5 defines the tagged-value encoding (
{"$type":"bigint","$value":"<digits>"}) and puts exactly one obligation on the server: "Servers MUST accept the registered types" (SPEC.md:97). That is inbound only.On the response side, S6.1 (
SPEC.md:118) says row values "use the same JSON / tagged-value encoding as section 5." That names an encoding. It does not oblige anyone to emit it.So a conforming server may return a stored SQLite INTEGER above 2^53 as a bare JSON number, and a JavaScript client rounds it. No rule is broken.
Why the conformance suite cannot catch it
P-5 roundtrips a
bigintthe client sent. A server that echoes what it was handed passes P-5 while still rounding every large value that was already in the table. The test needs to read a large integer the client never sent -- insert via literal SQL text, then SELECT it back.Why a spec edit alone does not close it
This is the part that matters for tracking.
encodeValuein both Cloudflare examples keys on the JS runtime type the driver handed back:By the time
encodeValuesees anumber, the driver has already rounded it -- the original 64-bit value is gone and is not recoverable at the encoding layer. So the fix is spec text PLUS driver configuration (D1/DO must be asked for bigints rather than numbers where the API allows it).Do not let this issue be closed by an implementation that still loses the value. That is the specific failure mode worth guarding against here.
Proposed resolution
Acceptance
encodeValue.Related:
lastInsertIdis the same data-loss class, filed separately.Origin: codex spec review; source-level sharpening (the
encodeValuerecovery point) by smugglr.