Skip to content

jsonrpc: numeric request IDs above 2^53 lose precision #1376

Closed

Description

@skosovsky

Describe the bug

Decoding the numeric JSON-RPC request ID 9007199254740993 changes it to 9007199254740992. This affects request/response correlation: a server can execute a request successfully but echo the wrong ID, and distinct numeric IDs can collapse to the same internal ID.

To Reproduce

Run this program with github.com/modelcontextprotocol/go-sdk v1.8.0:

package main

import (
    "fmt"

    "github.com/modelcontextprotocol/go-sdk/jsonrpc"
)

func main() {
    input := []byte(`{"jsonrpc":"2.0","id":9007199254740993,"method":"ping"}`)
    msg, err := jsonrpc.DecodeMessage(input)
    if err != nil {
        panic(err)
    }
    output, err := jsonrpc.EncodeMessage(msg)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(output))
}

Expected behavior

The ID remains 9007199254740993:

{"jsonrpc":"2.0","id":9007199254740993,"method":"ping"}

JSON-RPC requires the response ID to match the request ID: https://www.jsonrpc.org/specification#response_object

Logs

Actual output:

{"jsonrpc":"2.0","id":9007199254740992,"method":"ping"}

A separate raw HTTP reproduction against an SDK Streamable HTTP server also returned HTTP 200 with ID 9007199254740992 for a successful tools/call request whose ID was 9007199254740993. The application handler did not manipulate IDs. String ID "9007199254740993" was preserved correctly.

Additional context

Proposed fix: #1375. It preserves numeric IDs within int64, keeps integral decimal/exponent forms, and preserves cancellation request IDs. The regression test fails before the patch and passes afterward; full Go tests and targeted race tests pass. The PR also documents the numeric cancellation field's dynamic type change to json.Number and the int64 range boundary. The fix is proposed, not yet merged or released.

Activity

  1. added a commit that references this issue on Oct 15, 2026
    95591a7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions