SAEED MAGENTO DEVELOPER

SEARCH the site

Hit Enter to search or ESC to close

Cross

Blog / Debugging

Why your form says "success" but loses the lead

Why your form says "success" but loses the lead

TL;DR

  1. A "success" message on the front end proves nothing about the back end.
  2. Intermittent, per-tester failures almost always point to caching or a race, not a single broken line.
  3. Email that "sometimes" arrives is usually a deliverability problem, not a form problem.
  4. Reproduce the bug, find the root cause, document it, then verify the fix. Never patch a live site blind.

A client came to me with a familiar nightmare. Two business-critical lead forms, a booking form and an order form, had been behaving inconsistently for weeks. In a structured test with six people across different days, devices and browsers, five hit an error, each one a different combination. Lead volume was visibly down. Here's how I found the cause, and why the "success" message was lying to everyone.

The symptom that misleads everyone

The most dangerous part of this bug was the green checkmark. Visitors submitted the form, saw "Thank you, we'll be in touch," and walked away happy. But in the backend, the entry often never appeared. Confirmation and admin emails fired only sometimes. To the business, it looked like demand had dried up. In reality, the leads were arriving and vanishing.

The core lesson

A front-end success state is just JavaScript reacting to a request it sent. It isn't proof the server stored anything. If submission and confirmation aren't transactional, "success" is a guess.

Step 1: Make it reproducible

"It's intermittent" is not a bug report you can act on. It's a starting point. I built a reproduction matrix covering device, browser, logged-in versus logged-out, cold load versus warm load, and time of day. Running through it, a pattern surfaced that no single tester could have spotted alone: failures clustered on first page load from cache, and on the booking form's busiest time slots.

Step 2: Follow the request, not the UI

With the network panel open, the truth showed up quickly. On the failing submissions, the AJAX request carried a stale security nonce. The page had been served from full-page cache, so its token had already expired by the time the visitor submitted. The server rejected the write, but the front-end script still rendered success anyway.

// The shape of the problem
POST /wp-admin/admin-ajax.php
  action: form_submit
  _nonce: "a1b2…"   // served from cache, already expired

// Server: 200 OK, but body = { saved: false }
// Front-end: ignored the body, showed "Success" anyway

That single mismatch explained nearly everything: the missing entries, the inconsistent behaviour across testers, and why it correlated with cached page loads. The time-slot dropdown that "froze" turned out to be a second, smaller issue: a script initialising before its data on slow connections.

Step 3: The email half of the problem

Even on successful saves, emails were unreliable. The site was sending mail straight from PHP with no authenticated transport. Some messages slipped through; many were silently dropped or filed as spam by receiving servers. There was no SPF alignment, no DKIM signature, and no DMARC policy, so mailbox providers had every reason to distrust the mail.

The deliverability fix

  • Authenticated SMTP / transactional provider instead of raw PHP mail, so sending is logged and retryable.
  • SPF record listing the authorised senders.
  • DKIM signing so each message is cryptographically verified.
  • DMARC policy to tell receivers what to do, and to start getting reports.

Step 4: Fix, document, verify

The repairs themselves were small once the causes were clear: exclude the form pages from full-page cache (and refresh the nonce via a lightweight request on cached loads), fix the dropdown's init order, enforce the 24-hour lead-time rule on the server as well as the client, and route all mail through authenticated SMTP.

Non-negotiable

Every change went to staging first. The brief was explicit: previous updates had broken front-end rendering, so nothing touched production until the full test matrix passed clean.

The verification run repeated the original six-tester test across browsers and devices. This time: six of six passing, every submission stored, every email delivered. The fix shipped with a short root-cause report the client could keep, because the next developer deserves to know what happened here.

If you take one thing from this

Inconsistent bugs feel random. They almost never are. A success message you can't trace, mail that "usually" arrives, behaviour that changes by browser: these are signatures, not mysteries. Reproduce it properly and the cause stops hiding.

Got a bug that only happens "sometimes"?

That's exactly the kind of problem I like. Send me the symptoms and I'll find the cause.

Avg. reply < 24h · Mon–Fri