The Debugging Checklist
Everything in this chapter compresses onto one card. When an API misbehaves, people who are good at this do not stare harder or type the same request with more conviction. They walk a fixed list, in order, and the list almost always ends before the panic would have started. Nothing on it is new to you — every line was taught somewhere in the last six chapters. What is new is the order, and the promise to follow it.
Pilots run a printed checklist before every takeoff, and not because they forget how airplanes work. It is because pressure eats judgment, and a list does not feel pressure. That is the only superstition this book asks you to adopt: when something is broken and your pulse is up, run the list in order rather than following the most interesting hunch.
Step One: Reproduce With One curl
Strip everything away. Not the app, not the browser tab with eleven others beside it, not the graphical client with a saved setting you configured last month and have since forgotten. One command that shows the problem, typed fresh.
This is the promise from Chapter 3 finally being cashed. If the single command reproduces the failure, you now have a portable, honest specimen you can vary, keep, and send to anyone. And if the command works while the app still fails, that is not a disappointment — it is the best possible outcome, because the fault has just been located in the layer you removed, and half the suspects have left the room.
Step Two: Read What Actually Came Back
Look at the status line first for the family: 2 worked, 4 means your side, 5 means theirs. Then read the body properly — the machine label, the human sentence, the request id, in the order Topic 29 laid out.
Skipping this step is the single most expensive habit in beginner API work, because the answer is very often printed on the screen in a full sentence while the reader is off checking their internet connection. Read it out loud if that helps. It takes six seconds and it ends perhaps half of all incidents on the spot.
Step Three: Isolate the One Difference
If it used to work, something changed, and there is a short list of usual suspects. A token that has since expired. A different version in the address than the documentation page you were reading. A parameter with a typo, quietly ignored by the server, so the answer is wrong without being an error. A test key where a live one belongs, or the reverse.
The discipline is boring and undefeated: change one thing, resend, observe. Two changes at once and a success tells you nothing about which one mattered. This loop dissolves whatever the first two steps left standing, and it is the closest thing to a technique that debugging actually has.
Step Four: Verify Against the Docs, Then the Wire
Now open the reference page and compare, line by line: the endpoint and its verb, the required parameters, the field names you expect back, and the error list that may well already describe exactly what you are looking at.
If the documentation and the response disagree, the response wins. Chapter 6 settled that argument and the rule has not softened: the page describes the API, the server is the API. Note the gap, work with what the wire actually sends, and report the drift when you are done firefighting.
Step Five: Escalate Like a Partner
Some problems are genuinely on the other side, and then the goal is one message that can be answered on the first reply. Five things go in it, and nothing else does.
Redacting the key is not optional. Topic 22 was clear that a key is a password, and a support ticket is a document that gets forwarded, pasted, and archived. Replace it with tnd_live_XXX before the message leaves your hands.
curl -i -H "Authorization: Bearer tnd_live_XXX" \
https://api.tandem.example/v1/stations/st_014
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
{"error": {"code": "internal_error",
"message": "Unexpected error handling request",
"request_id": "req_9f2c"}}
That is a message Jonas can act on immediately. There is nothing to ask you for, nothing to guess at, and nothing to reproduce from a vague description — the command is right there, and the id points at his own logs. A first reply that solves the problem, instead of a first reply asking for more details, is what the five lines buy you.
- "Debugging is a talent, and I do not have it." It is a procedure, and you have just been handed it. What looks like talent from the outside is mostly somebody running this list quickly because they have run it many times before.
- "More context in a bug report is always better." The minimal reproduction is the gift. Three screenshots of the app are noise around the one curl command that is signal, and they make the reply slower rather than faster.
- "Escalating means I failed to solve it myself." Escalating with evidence is the system working as designed. The two actual failure modes are suffering in silence, and sending an evidence-free message saying it is broken.
- "If the app is broken, curl will be broken too." Often it is not, and that difference is information rather than an inconvenience. A working curl next to a failing app locates the fault in the app, which is genuine progress.
- This card is the practical climax of the book so far: Chapters 2 through 7 compressed into five moves you can run from memory, and the one page here most worth pinning above a desk.
- The evidence-first habit makes you the kind of caller providers answer first. Five lines of typing buys it.
Knowledge Check
Why does the checklist begin with reproducing the problem in one curl command?
- Because curl reaches the server faster than an app or a browser does
- Because it strips away every layer that could be causing the problem
- Because providers refuse to accept bug reports in any other format
- Because curl reveals error details that applications deliberately hide
Your curl command works, but the app that makes the same request still fails. What does that tell you?
- Nothing useful yet, so the reproduction attempt should be discarded
- The problem is in the app, not in the API or your credentials
- The API fails intermittently and you happened to catch a good moment
- The key works for curl but is rejected when the app presents it
What makes a reproduction "minimal"?
- It is the shortest command you can write, whether or not it still fails
- It is the smallest request that still reproduces the problem reliably
- It is a short written summary of what went wrong, without any command
- It is the full set of logs and screenshots gathered while investigating
What belongs in the escalation email to Jonas?
- The endpoint, your curl command with the working key left in, and the response
- A clear description of the symptoms and how long they have been happening
- The endpoint, expected versus actual, the redacted curl, the request id, the time
- Screenshots of the app failing, taken at several points during the incident
You got correct