Silent failures: when users are stuck and your error tracker sees nothing
Bottom line
The most expensive failures on your site throw no error. A button wired to nothing, a form that submits into the void, a CTA whose handler never attached: the browser considers all of them correct, so every technical monitor stays green. askbowtie catches them from the other side, by watching what users DO. Rage clicks, dead interactions, and submits that never complete fire precisely when technical signals cannot. get_incidents surfaces them ranked by business impact, get_incident_detail returns the failing page and the exact CSS selector, and get_conversions prices what the breakage costs. askbowtie does not fix your site. It tells your agent which element is broken, where it lives, and which silent failure to fix first.
The problem: everything says fine, nothing works
Your uptime monitor pings the page: 200 OK. Your error tracker watches the console: silence. Your analytics shows sessions arriving. By every technical measure the site is healthy.
Meanwhile a user is clicking "Start Free Trial" for the fourth time, harder, because nothing happens.
A button with href="#", an empty handler, or a listener that never attached works exactly as coded. It is not a bug to the browser. Check what actually fires:
| Signal | Does it fire? |
|---|---|
| JavaScript error | No |
| 404 | No |
| Failed network request | No |
| Console warning | No |
| Uptime alert | No |
If the link pointed at a missing page, a 404 monitor would catch it. But #, an empty href, or an unwired click handler produce zero signal. Nothing went wrong, technically. Something went very wrong, commercially.
Error tracking catches things that go wrong. Rage clicks catch things that don't go at all.
The idea: watch the user, not the console
Every monitoring tool you own watches the machine. askbowtie also watches the human, through the same lightweight tracker that records your analytics. If the code emits no signal, the visitor still does. The tracker already records every click with its element class, href, and selector, so it can tell an ordinary interaction from a frustrated one:
| Click pattern | What it means |
|---|---|
| Single click, moves on | Normal interaction |
| Double-click | Intentional (text selection, open file) |
| 3+ rapid clicks, same element | Rage click: something isn't responding |
Rage clicks are the flagship signal, but three behaviors mark a silent failure:
| Behavior | What it looks like | What it usually means |
|---|---|---|
| Rage click | 3+ rapid clicks on the same element within a second or two | The user expected a response and got none |
| Dead click | A click on something that looks interactive, with no navigation, no request, no DOM change | Placeholder link, missing handler, disabled logic gone wrong |
| Submit that never completes | Form interaction and a submit click, but the conversion event never follows | Validation dead-ends, handler swallowed the submit, request silently dropped |
None of these need instrumentation. The failure pattern is in click data you already have; askbowtie surfaces it as an incident, in the same pipeline as JavaScript errors and failed requests. That matters because incidents are ranked by impact: rage clicks on a checkout button outrank a console warning on the blog, every time.
How dead elements ship in the first place
They are not rare, and they are almost never caught in review, because the element looks finished:
- Placeholder links that shipped. A developer adds a button before the destination exists, sets
href="#", plans to come back. Nine out of ten get fixed. The tenth ships. - Conditional logic that fails silently. An edge case keeps the click handler exiting early. Renders fine, looks clickable, does nothing.
- Third-party scripts that didn't load. The chat widget or payment form behind the button was blocked by an ad blocker. Sometimes that throws a ReferenceError. Often it doesn't.
- Deploys that orphan event listeners. A deploy changes the DOM, the handler's selector no longer matches, and the button renders with no JavaScript attached. Zero console errors.
QA clicks the main flows. Nobody clicks every secondary CTA after every deploy. Real users do, and they are the first to find the dead one.
The worked example: from "conversions dipped" to the exact selector
Here is the agent loop on a real question (demo data throughout):
Owner asks: "Checkout traffic is normal but conversions dipped this week, and there are no errors. What's going on?"
get_incidents { domain: "shop.com", period: "7d" }returns active issues ranked by impact. Top of the list: typerage_click, 214 sessions affected, concentrated on/checkout. The class split shows nojs_errororhttp_5xxmovement: the technical side really is clean.get_incident_detail { domain: "shop.com", type: "rage_click", period: "7d" }returns the signature-level evidence: page/checkout, selectorbutton.apply-coupon, 214 occurrences this week, near zero the week before, and no accompanying error message. Users are hammering the coupon button and getting nothing.- The agent inspects
button.apply-couponin the page source: a deploy five days ago changed the DOM and orphaned the button's click handler. No error, no alert. get_conversions { domain: "shop.com", period: "7d" }prices it: the conversion dip starts the same day as the deploy.get_engagement { domain: "shop.com", page: "/checkout", period: "7d" }sharpens the number: sessions that engagedcta:place-orderconverted at 41%, while sessions that touchedapply-couponconverted at 3.1%. Roughly 200 sessions a week hit a dead button at the moment of payment.
The fix took one line. Finding it took four tool calls instead of a support ticket, if an annoyed customer ever bothered to send one.
Once your agent has the selector, the diagnosis is usually one of four things:
| Cause | Example | Fix |
|---|---|---|
| Placeholder link | href="#" |
Add real destination or remove link styling |
| Missing handler | Button with no click event | Wire up the event handler |
| Async dependency | Handler waits for a script to load | Defer interaction or add a loading state |
| CSS issue | Element looks clickable but isn't | Fix cursor and hover states, or make it interactive |
Frustration only matters when it's joined to money
A rage click count on its own is trivia. The same count joined to conversion tracking is a priority list (demo data):
| Element | Rage clicks/week | Conversions from those sessions | Priority |
|---|---|---|---|
| "Start Free Trial" on landing page | 200 | 0 | Fix now |
| "Buy Now" on product page | 80 | 3 (baseline: 40) | Fix now |
| Settings toggle in admin | 15 | Not a conversion path | Next sprint |
| Footer link to blog | 10 | Not a conversion path | Low |
The math is straightforward. If a broken button draws 200 rage clicks a week, none of those sessions convert, and your baseline conversion rate is 5%, that button costs roughly 10 conversions a week. Multiply by average order value and the fix justifies itself.
This join is the point of askbowtie's design: incidents, clicks, and conversions live in one per-site database, so "users are frustrated here" and "it is costing this many conversions" are one query apart, not three tools apart. For the framework on ranking what to fix first, see Not All Errors Are Equal.
The checklist nobody runs
QA can't click every element after every deploy, but two habits close the gap:
- After every deploy, ask your agent for
get_incidentsover the hours since. New rage-click signatures right after a deploy are orphaned handlers until proven otherwise. - Weekly, review behavioral incidents. An element that shows up twice is not a fluke: it's a dead button real users keep finding before your team does.
Questions you can now answer
- Is anything silently broken right now, even with zero errors? ->
get_incidents: rage clicks and dead interactions ranked by impact next to the technical classes. - Which exact element, on which page? ->
get_incident_detail { type: "rage_click" }: the CSS selector, page, and any co-occurring error message. - Is it costing conversions? ->
get_engagementon that page: the element's session share against its downstream conversion rate, checked againstget_conversions. - Did the last deploy kill a button? ->
get_incidentswith a period starting at the deploy, diffed against the week before. - Are form submits completing? ->
get_engagement(submit clicks present) joined withget_conversions(conversion events absent) for the same page and window. - Is the error tracker's silence real health or a blind spot? ->
get_incidents: if behavioral types are active whilejs_erroris flat, it's a blind spot. - Which broken thing do I fix first? -> the incident ranking already answers this: impact, not frequency.
MCP reference (for agents)
Tools (askbowtie MCP, in the question-to-tool order of a silent-failure investigation):
get_incidents { domain, period? }-> active issues ranked by impact. Behavioral types (e.g.rage_click) appear alongside technical classes (js_error,broken_page,broken_asset,http_5xx, third-party). Headlinetotalcounts distinct problems,sessions_affectedcounts distinct sessions, and per-issuecountis raw occurrence rows: three different numbers, never conflate them. Classes flaggedthird_party:trueare vendor scripts failing on the vendor's side, not the site's bugs.get_incident_detail { domain, type, period?, limit? }-> signature-level evidence for one incident type from get_incidents: CSS selector, page, error message (often absent for behavioral types, which is itself the diagnosis), request URL, HTTP status. One call per type.get_engagement { domain, page, period?, limit? }-> how viewers of one page actually interact: per sectionsessions_engaged,share_pct, downstreamconversion_rate, plus an unknown bucket,no_interaction_sessions, andsuggestionsof unnamed click signatures (by class/href). This is where a dead element's cost shows up: engaged share with near-zero downstream conversion.get_conversions { domain, period? }-> converting sessions (once per session, not raw events) and top converting pages. Join against engagement to confirm submits are completing, and to price a hotspot.
Recommended loop for "nothing is erroring but something is wrong":
get_incidents-> is a behavioral type active while technical classes are quiet?get_incident_detail { type }-> which selector, which page, is there a co-occurring error (fix that first if so)?get_engagement { page }-> what share of viewers touch that element, and at what downstream conversion rate vs the rest of the page?- Report the element, the page, the sessions affected, and the conversion gap. State rates as "sessions that engaged X converted at Y%": it is correlation, not attribution.
- After the fix ships, re-run
get_incidentsto confirm the hotspot goes quiet.
Gotchas:
- No error message on a rage-click signature is a finding, not missing data. It means the element fails without throwing, the exact class of failure error trackers cannot see.
- Low session counts make every rate noise. Read
sessions_affectedandviewed_sessionsbefore ranking anything. - Rage clicks can also be a pure UX problem (an element that looks clickable but isn't meant to be). The conversion join is what separates annoying from expensive.
For the full detective work on finding a silently broken form before it costs you leads, see how I trace a silently broken form.
Related pages
Cluster: Error monitoring: the complete guide to catching and fixing website errors.
Related: Not All Errors Are Equal: the framework for deciding what to fix first. Conversion tracking: the money side of every join on this page.
Docs: https://askbowtie.com/docs/ · Connect a site: https://askbowtie.com/