What a support ticket is really telling you
The report is a description of symptoms. The bug is somewhere else, and the gap between them is the whole job.
Every ticket is a little story about what someone was doing when the software let them down. “Submitting the purchase order throws an error.” That one line hides a screen, a button, a role, a site with its own data, a version, and a stack trace nobody pasted. It usually also hides a theory about the cause, stated as fact, and usually wrong.
I used to treat that story as the spec for the fix. It’s not. It’s a hint about where to start reading.
The symptom tells you where, not why
A submit failing tells me that code path ran. That’s actually useful; it rules out most of the codebase in one go. What it doesn’t tell me is which of the twenty things on that path broke. The reporter’s guess is worth about as much as any other guess, including mine.
So I read the path before touching anything. Where does the error message live? Who calls that function, and when? Nine times out of ten the answer is something the ticket never mentioned. A permission the user has and I don’t. A field left empty. A document created before some migration ran.
That gap between “here’s what the user saw” and “here’s the line” is the actual job. Skip it, and I end up fixing whatever looks broken near the crash. The traceback goes away and the bug stays.
Reproduce it first
The fastest way to learn I’ve misread a ticket is to try reproducing it and fail. That failure is useful too. Either the report is missing a condition, or what’s being described isn’t what happened.
I’d much rather spend twenty minutes reproducing than an hour fixing a bug that doesn’t exist. And once I can reproduce it, I get the one thing a ticket never gives me: a way to know I’m done.
Some tickets aren’t bugs
A fair number of reports describe the software working exactly as designed, written by someone who wanted it designed differently. That’s still worth hearing, but it needs a different answer than a patch. Often there’s already a setting that does what they want, and pointing them to it beats adding a second way to do the same thing.
Telling these apart takes reading the code, not reading the ticket harder.
One sentence, no UI
Before writing any code, I try to describe the bug in one sentence that doesn’t mention the UI at all. “Submitting throws an error” turns into “the validate hook reads a field that rows created before v15 don’t have.”
If I can’t write that sentence, I don’t understand the bug yet. Whatever I write next is a guess dressed up as a diff.