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
jsonrpc: decimal and exponent integer IDs still lose precision after #1401 #1404
After #1401 (95591a7), integer-literal request IDs retain their precision, but equivalent decimal/exponent forms still go through the float64 fallback in MakeID.
Reproduction through both DecodeMessage and MakeID(json.Number(...)):
Input ID
Expected numeric value
Actual
9007199254740993
9007199254740993
9007199254740993
9007199254740993.0
9007199254740993
9007199254740992
90071992547409930e-1
9007199254740993
9007199254740992
-9007199254740993.0
-9007199254740993
-9007199254740992
For example, decode {"jsonrpc":"2.0","id":9007199254740993.0,"method":"m"}. The decoded Request.ID.Raw() is 9007199254740992. The same occurs for response decoding.
Cancellation also uses MakeID: an integer request ID of 9007199254740993 does not match notifications/cancelled with requestId 9007199254740993.0 or 90071992547409930e-1.
These values are mathematically integral and within int64. Preserving their numeric value does not require retaining the original decimal spelling. JSON-RPC requires the response ID value to match the request: https://www.jsonrpc.org/specification#request_object.
Proposed scope: keep the integer-literal fast path, then normalize integral decimal/exponent forms exactly without exponent-sized allocations. Preserve the current fallback for genuinely fractional/out-of-range values and the existing float64 API behavior. The stricter rejection policy proposed in #1178 is separate.
@skosovsky we decided to introduce the fallback to float64 to keep backward compatibility and keep the MakeID() simple. JSON-RPC 2.0 §4 discourages fractional/exponential IDs.
Is this an issue you are actively facing?
We haven't confirmed these decimal/exponent IDs in production client traffic. We found this through SDK migration and protocol regression tests for our Zalo MCP server. Our current SDK fork already preserves these values exactly, so this is a compatibility gap we need to close before switching back to the upstream SDK, rather than an active production incident.
Independent prototyping note: I built and tested a fix for this before noticing that #1405 already covers it (my PR #1493 was auto-closed by the unassigned-contributor policy — no action needed). A few cases that may help whoever lands this:
worth asserting in the regression table: 9007199254740993.0, 90071992547409930e-1, 1.5e2 (→ 150), 0e1000000, the -9223372036854775808 boundary, and a genuinely fractional 1.5 staying on the float path;
normalize only when the literal is exactly an integer within int64 range — decimal or exponent spelling alike — so ID equality is restored across DecodeMessage / MakeID / notifications-cancelled matching without changing existing semantics.
Happy to hand over my test table if that saves #1405 review time.
Activity
guglielmo-san commentedon Oct 16, 2026
@skosovsky we decided to introduce the fallback to float64 to keep backward compatibility and keep the MakeID() simple. JSON-RPC 2.0 §4 discourages fractional/exponential IDs.
Is this an issue you are actively facing?
skosovsky commentedon Oct 16, 2026
We haven't confirmed these decimal/exponent IDs in production client traffic. We found this through SDK migration and protocol regression tests for our Zalo MCP server. Our current SDK fork already preserves these values exactly, so this is a compatibility gap we need to close before switching back to the upstream SDK, rather than an active production incident.
Shanmukh-l33t commentedon Nov 3, 2026
Independent prototyping note: I built and tested a fix for this before noticing that #1405 already covers it (my PR #1493 was auto-closed by the unassigned-contributor policy — no action needed). A few cases that may help whoever lands this:
9007199254740993.0,90071992547409930e-1,1.5e2(→ 150),0e1000000, the-9223372036854775808boundary, and a genuinely fractional1.5staying on the float path;Happy to hand over my test table if that saves #1405 review time.