The 7 console errors behind most "the button does nothing" bug reports
"I clicked Pay and nothing happened."
Nine times out of ten, the explanation for that sentence is already sitting in the browser console, in red. The person reporting the bug just never opened it.
This post is a field guide to the console for bug reports: what writes to it, which errors matter, what the common ones actually mean, and a routine for capturing the right lines. It's useful whether you're the developer reading reports or the person writing them.
What the console is (and who writes to it)
The console is one panel in the browser's developer tools. Two things write to it:
- The page's own code, through calls like:
console.log("cart loaded", cart); console.warn("coupon endpoint is deprecated"); console.error("checkout failed", err); - The browser itself, which reports uncaught errors, failed resource loads, security blocks and deprecation warnings, whether or not the developers logged anything.
You don't need to understand the code to use it in a bug report. The job is to notice the red lines that showed up when the problem happened and copy them.
Log levels, quickly
| Level | How it looks | What it usually means |
|---|---|---|
| Error | Red, often with a stack trace | Something failed. Most relevant to a bug report. |
| Warning | Yellow | Something may be wrong or is deprecated. Sometimes relevant. |
| Info / log | Plain text | Messages developers added. Context, rarely the cause. |
| Debug / verbose | Hidden by default | Detailed tracing for developers. |
The 7 errors you'll see most, decoded
1. TypeError: Cannot read properties of undefined (reading 'x')
The code expected some data that wasn't there, often because an API returned something unexpected.
// API returned { error: "expired" } instead of { data: { amount: 42 } } const total = response.data.amount; // TypeError: Cannot read properties of undefined (reading 'amount') Next step: check the Network panel at that same moment. The request that fed this code probably failed or returned an odd shape.
2. Uncaught (in promise)
An async operation (usually a request) failed and nothing handled the failure.
button.addEventListener("click", async () => { await fetch("/api/checkout", { method: "POST" }).then(r => r.json()); // no try/catch: if this rejects, the UI just... does nothing }); The visible symptom is very often a button that does nothing. That's the classic report.
3. Failed to load resource: the server responded with a status of 404
A file or API address doesn't exist. If you see 500 instead, the server failed.
4. Access to fetch ... has been blocked by CORS policy
The browser refused a request to another domain because that server didn't allow it. This is a server configuration issue, not something the user did. Don't let it get triaged as "user error".
5. ReferenceError: x is not defined
The code used something that doesn't exist, often because a script failed to load or loaded in the wrong order.
6. Refused to load the script ... Content Security Policy
The site's security policy blocked a script. This is common right after someone adds a new third-party tool.
7. ResizeObserver loop (and similar warnings)
Usually harmless noise. Mention it only if nothing else appears.
How to open the console
- Chrome, Edge, Brave:
F12, orCtrl+Shift+J(Windows/Linux) /Cmd+Option+J(Mac) - Firefox:
F12, orCtrl+Shift+K/Cmd+Option+K - Safari: first turn on the developer features in Safari's Advanced settings, then
Cmd+Option+C - On a phone: only by connecting the phone to a computer. That's exactly why mobile bug reports so rarely include console output.
A 6-step routine for capturing the right lines
- Open the console before reproducing. Some messages only appear once.
- Clear old messages so only your attempt remains.
- Keep the log across page loads. For redirects or form submissions, tick "Preserve log" (Chrome) or "Persist Logs" (Firefox).
- Reproduce the bug and note which messages appear at the moment it goes wrong.
- Copy as text. Right-click and save or copy. Text is searchable; a screenshot of the console isn't.
- Check the Network panel too. Failed requests show in red with their status code. The console tells you what broke; the network panel often tells you why.
Before you paste logs anywhere
Console messages can contain email addresses, tokens or other personal data if someone logged them. Read the lines before sharing them outside your team, and remove anything that looks like a key or a password.
Also: opening and reading the console is safe, but don't paste code into it that someone else sent you. Code run in the console acts as you on that site.
"Why is the console full of errors on a site that works fine?"
Many sites log harmless warnings, blocked trackers and errors from third-party scripts. What matters is which messages appear when the problem happens, which is why step 2 (clear first) matters so much.
The catch: most reporters will never open DevTools
Clients, customers and most non-developer teammates won't do any of the above, and on mobile they can't. The practical fix is to have a script in the page collect the same information in the background and attach it to the report.
Disclosure: I'm building one of these, Flawsnap. Its website widget attaches the last 100 console messages and uncaught errors, plus the last 100 fetch/XHR requests (method, URL, status, duration), to each report. It never captures request or response bodies. If you want the logs from the very start of the page, load the script in the <head>. There's a no-sign-up demo with a deliberately broken checkout if you want to see what a captured report looks like. Whatever tool you use (or none), the routine above is the part that matters.
Your turn: what's the console error that cost you the most time to track down? Drop it in the comments. I'm collecting the weird ones.
This post was drafted with AI assistance and edited by me. It was originally published on flawsnap.com.