---
title: "Comment by Mike Dabydeen on \"MCP Tool Error Handling: 5 Calls, One Failure Hidden as Success\" | Hashnode"
description: "A flagged error from a tool that writes something still doesn't tell the agent whether the write happened. Your thrown_error row is the one I'd extend: if the h"
url: "https://hashnode.com/posts/mcp-tool-error-handling-5-calls-one-failure-hidden-as-success/6af181e5dca8f65f12d06742/comment/6af1bb7f6d1ced13cda358e3"
---

[Discussion](https://hashnode.com/posts/mcp-tool-error-handling-5-calls-one-failure-hidden-as-success/6af181e5dca8f65f12d06742)

Comment [MCP Tool Error Handling: 5 Calls, One Failure Hidden as Success](https://hashnode.com/posts/mcp-tool-error-handling-5-calls-one-failure-hidden-as-success/6af181e5dca8f65f12d06742)

[Mike Dabydeen](https://hashnode.com/@firelinks)

[4d ago](https://hashnode.com/posts/mcp-tool-error-handling-5-calls-one-failure-hidden-as-success/6af181e5dca8f65f12d06742/comment/6af1bb7f6d1ced13cda358e3)

A flagged error from a tool that writes something still doesn't tell the agent whether the write happened. Your thrown\_error row is the one I'd extend: if the handler throws "upstream timeout" after the upstream already committed, the client gets isError: true, and the obvious recovery is to call again, which repeats the write.

For side-effecting tools I'd put the effect state in the error text itself: not applied, applied, or unknown. Unknown is the honest answer for a timeout, and it should tell the agent to check status before retrying. If the tool also takes an idempotency key and the client reuses it on the retry, the server can return the first result instead of doing the work twice. That would make a sixth row for the fixture: a handler that commits and then throws, followed by a second call with the same key.

[Daniel Martin](https://hashnode.com/@averyellistech)

[4d ago](https://hashnode.com/posts/mcp-tool-error-handling-5-calls-one-failure-hidden-as-success/6af181e5dca8f65f12d06742/comment/6af1bb7f6d1ced13cda358e3#reply-6af1c02ac2533db561567690)

Good catch. My five-call fixture records the SDK result; it doesn’t test whether a write committed before a timeout. For a side-effecting tool, `isError: true` alone isn’t a safe retry instruction. A useful follow-up would commit once, simulate a timeout, retry with the same idempotency key, and check that the effect isn’t duplicated. Thanks for pointing out the gap.
