Blog

The ticket that says it does not work

5 min read

A ticket that says it does not work names a person, not a cause. Search the email they sent. The visit is the rest of the ticket.

A single blank ticket card on a desk, with one small copper mark in the corner.

A ticket that says it does not work is not an empty ticket. It names a person. The sentence they wrote is almost useless. The address they sent it from is the start of the investigation. Search that email. If the visit was recorded, you can see what they did, what your app did, and where it failed, without asking them to try again.

Bugwalk is an AI debug engineer for that visit. After identify() is called with an id or an email, page views, clicks, requests, errors, and logs stay on one timeline for that person. You start from the person who got stuck, not from an error that has no name on it.

What the ticket actually contains

Read a hundred of these and the sentences repeat. It does not work. The button does nothing. I tried again. Can you check? The useful facts are hiding in the header: who wrote, when they wrote, and sometimes which account they were in. The body is a mood. The header is an id.

The usual reply asks them to reproduce it. What page were you on. What did you click. What did you expect. Did you try another browser. Those questions are an attempt to rebuild the visit from memory, after the visit is over. People remember the stuck part. They forget the three steps before it. They will not remember the request your server rejected. You are interviewing a witness about a timeline you could have recorded.

A tall stack of identical blank cards, with one card pulled out and set aside.
The sentence is the same on every card. The address is not.

Start with the email

Copy the email off the ticket. Search it. Search takes an email or an id. A prefix is enough when that is all you can read. The person, once identified, keeps the visits that happened before the ticket and the ones that happen after. You do not need a new report from them to see the failure they already hit.

This only works if identify() ran when you knew who they were. One call after sign-in is enough. Events before that call join the same person. Backend requests during the visit attach when the browser SDK is present. If you never identify anyone, you have a pile of anonymous sessions and the email on the ticket matches nothing. The fix is in the app, at the moment you learn the id, not in the support queue.

Background work is a different path. A cron or a queue should not call identify() with a made-up id. That creates a person who is not a person. The docs on journeys are the place for the visit you can open from search. The install docs cover withWork and forPerson when the work is not a signed-in visit.

The visit is the ticket

Open the visit and read it in order. The page they were on. The click. The request. The status. The error. The log line written next to it. That sequence is what the ticket was trying to say, without the memory and without the mood. You can answer them with the page and the failure, instead of with a request to try once more while you watch.

One person has more than one visit. The ticket usually points at the latest one that failed, not at the whole history. Read that visit first. Then look at the one before it, if they tried twice, and at the issue if other people hit the same error. The history is how you tell a one-off from a cause. A single angry sentence cannot tell you that. The timeline can, because the attempts are still there after they closed the tab.

Stop asking them what they clicked. Open the visit and see the click.

A desk of blank cards, one of them marked in copper while the rest stay graphite.
One email. The rest of the pile can wait.

The same failure, seen across people, belongs on an issue. An issue groups events that share an error fingerprint, so you fix a cause once and you can see who else hit it. The ticket felt personal. The issue shows whether it was only them. Both views are the same events. One starts from the person. One starts from the error.

What you can stop asking them

You can stop asking which page, if the visit has the page. You can stop asking them to reproduce, if the failure is already on the timeline. You can stop asking for a screenshot of an error message you already stored. You still write back. The reply can say what failed and what happens next, which is a different letter from the one that asks them to become your logger.

You cannot stop asking when the visit is not there. A person who never signed in, a browser with the SDK blocked, a mobile webview you do not instrument: search returns nothing, and the ticket is all you have. Say so. Do not invent a session to make the queue look finished. A missing visit is a fact. The next step is to record the next one, or to ask the one question the timeline cannot answer.

When there is no email

Some reports arrive with an id, an account number, or a name your app already stores. Search that. Some arrive with nothing but a trace pasted into chat. Then you are back to the stack trace: a line, and no person. Ask for the email or the id before you ask them to tell the story again. The story is the expensive part. The address is the cheap part.

When the visit is open, an investigation can read it and the code that was live. That is the point where a ticket becomes a cause, and sometimes a pull request. Until then, the job is smaller than it looks. Find the person. Open the visit. Read what they did.

Questions

What should you do when a customer says it does not work?

Search the email or id they already sent. If the app called identify(), their visit is there: the page, the click, the request, and the error. You do not have to ask them to reconstruct it from memory.

Why does the ticket text not help?

The sentence is usually a mood: it does not work, the button did nothing, they tried again. The useful fact is who sent it. The visit holds the sequence they will not remember.

What if search finds no one?

Then the visit was not tied to that email or id. identify() has to run when you know who they are. A missing person is a fact. Do not invent a session to close the ticket.