@@ -1470,59 +1470,6 @@ func TestStreamableClientConnect_DiscoverUnsupportedVersion(t *testing.T) {
14701470 }
14711471}
14721472
1473- // TestStreamableClientConnect_DiscoverPropagatesOtherErrors verifies that
1474- // Client.Connect does NOT fall back to initialize when server/discover
1475- // returns an unrelated JSON-RPC error (here, CodeInternalError). The Connect
1476- // call should fail with the propagated error rather than masking it.
1477- func TestStreamableClientConnect_DiscoverPropagatesOtherErrors (t * testing.T ) {
1478- ctx := context .Background ()
1479-
1480- var sawInitialize atomic.Bool
1481- fake := & fakeStreamableServer {
1482- t : t ,
1483- responses : fakeResponses {
1484- {"POST" , "" , methodDiscover , "" }: {
1485- header : header {"Content-Type" : "application/json" },
1486- wantProtocolVersion : protocolVersion20260630 ,
1487- responseFunc : func (r * jsonrpc.Request ) (string , int ) {
1488- return jsonBody (t , & jsonrpc.Response {
1489- ID : r .ID ,
1490- Error : & jsonrpc.Error {
1491- Code : jsonrpc .CodeInternalError ,
1492- Message : "boom" ,
1493- },
1494- }), http .StatusOK
1495- },
1496- },
1497- {"POST" , "" , methodInitialize , "" }: {
1498- responseFunc : func (r * jsonrpc.Request ) (string , int ) {
1499- sawInitialize .Store (true )
1500- return jsonBody (t , & jsonrpc.Response {ID : r .ID , Result : mustMarshal (initResult )}), http .StatusOK
1501- },
1502- header : header {
1503- "Content-Type" : "application/json" ,
1504- sessionIDHeader : "fallback" ,
1505- },
1506- optional : true ,
1507- },
1508- },
1509- }
1510-
1511- httpServer := httptest .NewServer (fake )
1512- defer httpServer .Close ()
1513-
1514- transport := & StreamableClientTransport {Endpoint : httpServer .URL }
1515- client := NewClient (testImpl , nil )
1516- session , err := client .Connect (ctx , transport , & ClientSessionOptions {protocolVersion : protocolVersion20260630 })
1517- if err == nil {
1518- _ = session .Close ()
1519- t .Fatal ("Connect succeeded; want propagated error" )
1520- }
1521- if sawInitialize .Load () {
1522- t .Error ("server received initialize; Connect should have aborted on the discover error" )
1523- }
1524- }
1525-
15261473// TestStreamableClientConnect_DiscoverMethodNotFoundVPre verifies that
15271474// Client.Connect falls back to the legacy initialize handshake when a
15281475// pre-SEP-2575 (vPre) server rejects server/discover.
@@ -1635,3 +1582,68 @@ func TestStreamableClientConnect_DiscoverUnsupportedVersionVPre(t *testing.T) {
16351582 t .Errorf ("InitializeResult.ProtocolVersion = %q, want %q (initialize fallback)" , got , latestProtocolVersion )
16361583 }
16371584}
1585+
1586+ // TestStreamableClientConnect_DiscoverUnsupportedVersionNegotiation verifies that
1587+ // when Client.Connect over a streamable transport receives an
1588+ // UnsupportedProtocolVersion error containing Data.Supported, it negotiates a
1589+ // mutually supported version and retries server/discover.
1590+ func TestStreamableClientConnect_DiscoverUnsupportedVersionNegotiation (t * testing.T ) {
1591+ ctx := context .Background ()
1592+
1593+ oldSupported := supportedProtocolVersions
1594+ supportedProtocolVersions = append ([]string {protocolVersion20260630 }, supportedProtocolVersions ... )
1595+ t .Cleanup (func () {
1596+ supportedProtocolVersions = oldSupported
1597+ })
1598+
1599+ const unsupportedClientVersion = "2099-12-31"
1600+
1601+ var discoverCalls atomic.Int32
1602+
1603+ fake := & fakeStreamableServer {
1604+ t : t ,
1605+ responses : fakeResponses {
1606+ {"POST" , "" , methodDiscover , "" }: {
1607+ header : header {
1608+ "Content-Type" : "application/json" ,
1609+ },
1610+ responseFunc : func (r * jsonrpc.Request ) (string , int ) {
1611+ n := discoverCalls .Add (1 )
1612+ if n == 1 {
1613+ data , _ := json .Marshal (UnsupportedProtocolVersionData {
1614+ Supported : []string {protocolVersion20260630 },
1615+ })
1616+ respMsg := & jsonrpc.Response {
1617+ ID : r .ID ,
1618+ Error : & jsonrpc.Error {
1619+ Code : CodeUnsupportedProtocolVersion ,
1620+ Message : "unsupported protocol version" ,
1621+ Data : data ,
1622+ },
1623+ }
1624+ return jsonBody (t , respMsg ), http .StatusOK
1625+ }
1626+ return jsonBody (t , & jsonrpc.Response {ID : r .ID , Result : mustMarshal (discoverResult )}), http .StatusOK
1627+ },
1628+ },
1629+ },
1630+ }
1631+
1632+ httpServer := httptest .NewServer (fake )
1633+ defer httpServer .Close ()
1634+
1635+ transport := & StreamableClientTransport {Endpoint : httpServer .URL }
1636+ client := NewClient (testImpl , nil )
1637+ session , err := client .Connect (ctx , transport , & ClientSessionOptions {protocolVersion : unsupportedClientVersion })
1638+ if err != nil {
1639+ t .Fatalf ("Connect: %v" , err )
1640+ }
1641+ defer session .Close ()
1642+
1643+ if got , want := discoverCalls .Load (), int32 (2 ); got != want {
1644+ t .Errorf ("discover call count = %d, want %d" , got , want )
1645+ }
1646+ if got := session .InitializeResult ().ProtocolVersion ; got != protocolVersion20260630 {
1647+ t .Errorf ("InitializeResult.ProtocolVersion = %q, want %q" , got , protocolVersion20260630 )
1648+ }
1649+ }
0 commit comments