Zenaique

Spot the bug revealed by JSON-RPC tracing in this MCP exchange

Spot the error·Medium·4.0 · 0·~2 min·Asked atBainDeepseekTencent·Relevant atAnthropic
Attempt it

Click any words you think contain an error. Click again to unmark.

Mark at least one word to submit.
TL;DR

The response carries id 2 but the request was id 1. JSON-RPC correlates by echoing the request id, so the client can never match this reply.

Memory aid
Sign in to see the mnemonic that makes this stick.
Easy to grasp

Picture a busy coffee counter where everyone orders at once. The barista hands each order a numbered ticket and calls that number when the drink is ready. You hold ticket 1, but the barista shouts 'order 2!' and sets down your latte. You have no way to know it is yours, so you keep waiting while the coffee goes cold on the counter. JSON-RPC works the same way. The client tags each request with an id and keeps a list of tickets it is still waiting on. The server must reply with the exact same id so the client can match the answer to the right question. Here the request used id 1 and the reply came back as id 2, so the client never finds a match and the call stalls.

Concept explanation~2 min read

Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.

This is a transport bug, and the whole trick is knowing to look at the transport first. Both frames are valid JSON. The tool ran. The result, Alice's row, is exactly what you would expect from SELECT * FROM users. Everything at the application layer looks healthy. Yet the exchange is broken.

The defect is one character of meaning: the request was sent with id: 1, and the response came back with id: 2. In JSON-RPC 2.0, that id is the sole mechanism a client uses to match a response to the request that produced it. When the ids disagree, the match fails, and the call quietly dies.

This deep dive explains what the id is for, how a client uses it, exactly what goes wrong here, the two server-side bugs that cause it, and why this class of defect only shows up when you trace the raw protocol frames rather than the application logs above them.

What the id field is actually for

JSON-RPC 2.0 is an asynchronous, multiplexed protocol. A single connection between an MCP host and an MCP server can carry many requests at the same time. The host does not have to send a tools/call, wait for the reply, then send the next one. It fires several off and processes responses as they arrive.

That design creates a matching problem. If three requests are in flight and a response shows up, which request does it answer? The protocol solves this with the id field. Every request that expects a reply carries a unique id. The server is required to copy that exact id into its response. The id is the join key between a request and its response.

There is a deliberate consequence here. Because matching is by id, responses are allowed to come back in any order. The server can finish request three before request one. Ordering on the wire means nothing; only the id matters. That is precisely why the id cannot be a fresh value, it has to be the request's own id echoed back.

How the client uses the id
The exact failure mode here
The two server bugs that cause this
Why only tracing catches it
Designing a tracer that cannot miss this
Sign in to unlock the full deep dive.

Situations where this technique stops working.

Sign in to see when this approach fails.

2–4 min · Everything important, quickly.

Sign in to see the quick scan of the deep dive.
AspectCorrect responseBuggy response shown
id valueEchoes request id (1)New value (2)
Client lookupFinds pending entry for id 1Finds nothing for id 2
OutcomeCall resolves with the resultOriginal call hangs and times out
Data payloadAlice's row, correctAlice's row, still correct

Real products, models, and research that use this idea.

  • The mcp-inspector tool surfaces this by printing paired request and response frames so a mismatched id is visible at a glance.
  • Claude Code and Cursor multiplex many concurrent tools/call requests over one stdio connection, so id correlation is what keeps replies from crossing wires.
Sign in to see more production examples.

What an interviewer would ask next. Try answering before peeking at the approach.

QHow would you design the client's pending-request map to detect a mismatched or duplicate id early?
A

Key the map by request id; on response, fail loudly if the id is absent or already resolved, rather than silently dropping. Add a per-id timeout to convert hangs into clear errors.

2 more follow-ups an interviewer would ask next. Sign in to reveal them.

Red flags & common mistakes

The phrases that signal junior thinking. Click to expand.

Most common mistake

Looking at the SQL or the result payload for the bug. The transport layer is broken first: the response id does not match the request id, so correlation fails.

Sign in to see all red flags and common mistakes.

60 second bullets to scan on the way to the call.

  • Why JSON-RPC needs an id on every request

  • How a client maps a response back to its request

Sign in to unlock the revision sheet.

Primary sources. Browse if you want the original framing.

Similar questions

Same topic, related formats. Practice these next.

4 curated
Next question
What is the Model Context Protocol (MCP) and what problem does it solve?
MCQ·Easy