THIS EXPLANATION
THE ROOM
CDA·168 Computing, Data & AI 6 MIN · 8 STATIONS

Protocol errors versus execution errors

A Socratic walk-through of protocol errors versus execution errors — reasoned out one step at a time, not lectured.

abcdefgh
a

The question we started with

THE QUESTION #

Why is an operation that correctly reports it failed not a failure of the protocol?

A client asks a server to delete a file. The file is not there, and the server says so. Was that a failure?

Most people answer yes without hesitating, and in one sense they are right — the deletion did not happen. But hold the word still for a moment. Two quite different things could have gone wrong. The request might never have been understood at all. Or it might have been understood perfectly, carried out faithfully, and the honest answer to it is no such file. If we call both of those "an error", we have thrown away the distinction that determines what anyone should do next.

b

Reasoning it through

REASONING #

Ask what each kind of failure tells you about the system. When a message is malformed, or names a method the server does not have, or omits a required argument, the exchange itself has broken. Nobody learned anything about files. The right response is to fix the caller — and there is no useful information for anyone downstream, because no work was attempted.

Now the other case. The message arrived, was well-formed, named a real operation, carried valid arguments, and the server ran it. The result is that the file was absent. Everything about the exchange worked; what came back is a fact about the world. Notice that this is content, not a malfunction. It is precisely the sort of thing the caller asked to find out.

So the split is not between "worked" and "did not work". It is between the conversation broke and the conversation succeeded in delivering bad news. Which side something falls on has nothing to do with how disappointing the news is.

Why does the distinction earn a place in the protocol rather than just in a comment? Consider retries. A malformed request will fail identically forever — retrying is pure waste. A missing file might exist in a second, or might be a permanent condition, and only the caller's own logic can tell. If both arrive through the same channel with the same shape, a retry policy cannot distinguish them and will either hammer a hopeless request or give up on a recoverable one.

Consider, too, who the audience is. This matters especially when the caller is an AI assistant. A protocol error is addressed to the developer who wired the client up: the tool name was wrong, the schema was violated. Nothing the model can do in-conversation fixes that. An execution error is addressed to the model itself: the path does not exist, the query returned nothing, the account lacks funds. That is exactly the sort of thing a model can act on — try a different path, ask the user, report the shortfall. If a "file not found" is delivered as a transport-level fault, the model may never see the text at all, because the client will treat it as plumbing and swallow it.

This is why the Model Context Protocol, which runs over JSON-RPC 2.0, splits them structurally. A genuine protocol problem comes back as a JSON-RPC error object with a code — the standard ones such as method-not-found and invalid-params live in the negative thirty-two-thousand range. A tool that ran and failed comes back as an ordinary successful response whose result carries an isError flag and the failure text as content the model can read. The tool call succeeded; what it reports is bad news.

Is the boundary always obvious? No, and the honest cases are worth naming. If a server cannot reach its database, is that protocol or execution? The exchange worked, so it is execution — but nothing about the request was wrong either, and the caller may want to retry blindly, which looks like protocol behaviour. Timeouts sit similarly awkwardly. The workable rule is to ask whether the caller's message was answerable, not whether the answer was good: if the server understood you and formed a truthful reply, you had a successful exchange, however unhappy the contents.

c

The analogy

THE ANALOGY #
THE FIGURE

Think of asking a librarian for a book. If you speak a language they do not know, or ask for something that is not a book at all, the request itself failed — nothing was looked up, and the fix is to ask differently. If they understand you perfectly, walk to the shelf, and come back to say the book is on loan until Friday, the request succeeded: you now hold information you did not have, which is what you came for.

WHERE IT BREAKS DOWN

a librarian can tell you they misheard and let you try again in the same breath, whereas a protocol error typically terminates that exchange entirely — there is no repair turn, only a new request from a caller that has been fixed.

d

Clarifying the model

THE MODEL #

A few refinements.

The first is that this is a claim about layers, not about severity. An execution error can be catastrophic — a payment declined, a deploy rejected — and a protocol error can be trivial, a typo in a field name. Putting a failure on the execution side is not a judgement that it is minor; it is a statement about which layer has something to report.

The second is the common misreading in the other direction: that using the successful-response channel for a failure is somehow dishonest, a way of hiding errors. It is the opposite. The result payload carries an explicit failure flag and the human-readable reason, so the information is more visible, not less — and it reaches the party who can use it. What would actually hide the error is collapsing it into a transport fault that a middle layer logs and discards.

The third is that this shapes error text. Because execution errors are read by a model or a user rather than a debugger, they should say what happened and what might be tried, not carry a stack trace. And they should not leak internals — a message that names an internal host or path has turned an ordinary failure into an information disclosure.

e

A picture of it

THE PICTURE #
Protocol errors versus execution errors
Protocol errors versus execution errors the horizontal axis asks only whether the server understood and ran your request; the vertical asks whether you liked the answer. The bottom-left quadrant is protocol failure -- nothing was attempted, and the fix belongs to whoever wrote the client. The bottom-right is execution failure: the exchange worked and returned bad news, which is information the caller can act on. The top-left quadrant is empty by construction, because a request that was never understood cannot have produced a good outcome. {"generator":"[email protected]","source":"../Socrates/.diagram-cache/_src/protocol-errors-versus-execution-errors.md","sourceIndex":1,"sourceLine":4,"sourceHash":"eae38f53b2b772264a0927c13a2125938c0a37e9861505c5a2b26bde2ccedce7","diagramType":"quadrantChart","layoutVariant":"source","repairedDuplicateIds":[],"motion":"entrance-with-reduced-motion-fallback","presentation":"editorial","attempt":1,"viewBox":{"x":0,"y":0,"width":720,"height":621},"qa":{"passed":true,"findings":[]}} Ordinary success Q1 Cannot occur Q2 Protocol error Q3 Execution error Q4 Deletion completed Payment was declined File was not there Required argument missing Unknown method name Malformed request Message not understood Message understood and run Bad outcome Good outcome Where a failure actually happened

How to readthe horizontal axis asks only whether the server understood and ran your request; the vertical asks whether you liked the answer. The bottom-left quadrant is protocol failure — nothing was attempted, and the fix belongs to whoever wrote the client. The bottom-right is execution failure: the exchange worked and returned bad news, which is information the caller can act on. The top-left quadrant is empty by construction, because a request that was never understood cannot have produced a good outcome.

f

What became clearer

WHAT CLEARED #
WHAT CLEARED

The word "error" was doing two jobs. One names a breakdown in the conversation, where nothing was learned and the caller must be repaired. The other names a truthful, successfully delivered report that the world did not cooperate. Keeping them in separate channels is what lets retries be sensible, lets errors reach an audience that can act on them, and keeps a working protocol from being blamed for the news it faithfully carried.

g

Where to go next

ONWARD #
  • Where timeouts and unreachable dependencies honestly belong, given that they satisfy parts of both definitions.
  • How an agent should decide, from an execution error alone, whether to retry, change approach, or ask a person.
  • What error taxonomies in other protocols — HTTP's status classes, gRPC's status codes — get right and wrong about the same split.
h

Key terms

TERMS #
TermWhat it means
JSON-RPC 2.0the remote-call convention underlying several modern protocols, which distinguishes a result from an error object in every response.
Protocol errora failure of the exchange itself: unparseable message, unknown method, invalid parameters. No work was attempted.
Execution errora successfully delivered report that the requested work did not achieve its goal.
isError flagthe field in a tool result that marks the returned content as a failure report rather than a normal outcome.
Idempotencethe property that repeating an operation has the same effect as performing it once, which is what makes a blind retry safe.

Every term the collection defines is gathered in the glossary.

Nearby on the shelf

4