Skip to content
Back to all articles
Klaviyo Expert
Klaviyo Flows
Email Marketing
Retention
Case Study

Klaviyo Expert Field Notes: 11 Flow Defects That Quietly Kill Email Revenue

Real Klaviyo flow defects found in a production audit — broken dynamic coupons, SMS/email branching bugs, dead conversion metrics, UTM fragmentation — and how flow revenue recovered to ~$15.8K in 7 days.

August 24, 2026 13 min readBy Matheus Abrahão

Broken Klaviyo flows do not look broken

That is the whole problem. A flow with a fatal defect shows the same green Live badge as a flow that is printing money. The preview renders. The test send arrives. The dashboard shows sends going out.

And the revenue line is flat, and nobody knows why.

I audited a production Klaviyo account across two storefronts and found eleven distinct defects. Not "opportunities to optimise" — actual bugs, each one costing money every day it stayed live. Here they are, because I promise at least three are on your account right now.

1. Static text where a dynamic coupon belonged

The account had two properly configured dynamic coupon objects — prefix plus eight random characters, unique per recipient. Three emails printed the bare prefix as typed text.

Every single recipient received a code that does not exist.

Why nobody caught it: the prefix looks like a real coupon code. SAVE10 in the preview looks exactly like a working SAVE10. The only way to catch it is to look at whether the token in the editor is a variable or text — or to actually redeem the code from a real send.

2. Copy promising an expiry the coupon does not have

Emails said "valid for 5 days." The coupons were configured at 30 days.

This is not a copy nit, it is structural: a shared static code physically cannot give each recipient N days from their own send date. Only a dynamic coupon can. If your email says "expires in 5 days," you have committed to dynamic coupons whether you know it or not.

Same class of bug in the welcome email, where a literal [INSERT EXPIRY DATE] placeholder had been shipped to production. Fixed by rendering the date as send date plus N days.

3. A live transactional email advertising a deleted discount code

For roughly ten weeks, a live flow was sending a code that had been deleted from Shopify. Recipients clicked, applied it, and got a checkout error.

The fix had two parts, and the second is the one people skip: recreate the code as a bridge — matching the original's exact scope (percentage off a specific non-custom collection, one use per customer, no end date) — then retire it deliberately after the flow migration, rather than leaving a mystery code alive forever.

4. The SMS/email branch that silently muted a whole segment

The Abandoned Checkout flow branched on SMS consent. Anyone who was SMS-subscribed got exactly one text and zero emails.

Read that again: your most engaged subscribers — the ones who gave you their phone number — were the ones receiving the least communication about an abandoned checkout.

The correct shape is not a branch. It is a base and a bonus:

  • Everyone receives the full email sequence.
  • SMS subscribers additionally receive the text.

SMS is additive. If your flow chart has SMS on one side of a split and email on the other, you have this bug.

5. Empty product variables

Abandoned Cart and Browse Abandonment were rendering "you added ___ to your cart" — the product name variable resolving to nothing.

The catch is that this passes in preview, because preview injects sample data. The only reliable test is triggering the flow against a real event on the live store and reading the email that actually arrives.

6. Cross-flow double-hitting

Browse Abandonment was firing at people who had already added the item to cart, so they got a "still thinking about it?" email and a cart reminder about the same product within an hour.

Two fixes:

  • An exclusion filter on Browse Abandonment for anyone who has started checkout or added to cart.
  • A 30-day re-entry cooldown on Abandoned Cart, so a repeat visitor stops receiving the same email every week.

7. Flows pointed at a dead conversion metric

This one is my favourite because it makes a working flow report zero.

The account had two Placed Order metrics: one from the current Shopify integration (live, 22–35 orders/day) and one left over from a previous ecommerce platform whose integration had been removed years earlier. The old one still appears in the dropdown. It records 0 every single day.

Any flow whose conversion metric points at the dead one reports $0.00 revenue forever, no matter how well it performs. Teams then kill their best-performing flow because "it doesn't make money."

Check every flow's conversion metric. If your store has ever been migrated, check twice.

8. Inconsistent Smart Sending inside one flow

Smart Sending on for email 1, off for emails 2 and 3. Not a catastrophe, but it means your frequency cap is a suggestion, and it is the kind of drift that indicates nobody has reviewed the flow end-to-end in a long time.

9. Links pointing at the myshopify.com domain

Three welcome emails and a browse-abandonment product feed were linking to *.myshopify.com instead of the customer-facing domain. Plus several primary CTA buttons with href="#".

The myshopify links technically work — they redirect — but they burn a redirect hop, they look untrustworthy in a hover preview, and they break UTM attribution on some setups.

10. The popup and the flow were pointed at different lists

This is the one that cost the most.

The site popup deposited subscribers into List A. The Welcome Series triggered on List B.

Result: 8,276 email subscribers gained in 90 days, and a Live Welcome Series showing $0.00. A bucket being filled through a hole.

Related: two competing popups were running, one from the theme and one from Klaviyo. Important mechanic here — you kill the duplicate by disabling the individual form in Klaviyo, not by turning off the Klaviyo app embed in the theme editor. That embed powers the onsite tracking that feeds Browse Abandonment and Abandoned Checkout, which between them were doing about $6.6K/week. Turn off the embed and you turn off two revenue flows to fix a cosmetic problem.

11. UTM parameters set to the list name

The account had utm_source configured to resolve to the list or segment name. Every send produced a unique source value.

GA4 attributed the clicks correctly — and then never aggregated them, because "email" had shattered into dozens of one-off sources. The email channel looked tiny because it was spread across forty rows.

The fix is boring and correct:

  • utm_source — static. One value. klaviyo.
  • utm_mediumemail.
  • utm_campaign — carries all the detail.
  • Per-message UTM tracking enabled.

The second storefront had a worse version: the master UTM toggle was entirely off, so every link left with no UTM at all and analytics filed the traffic as direct. And that store's theme had no analytics tag installed either — so flipping the Klaviyo toggle alone would have changed nothing. Two independent fixes, both required.

An important nuance I put in writing for the client: revenue was still being captured correctly in Klaviyo the whole time, via Shopify's Placed Order metric. The GA4 gap was a reporting hole, not lost money. Those are very different problems and conflating them causes panic. On the wholesale account, a welcome flow was doing ~$32.7K/30 days that GA4 could not see at all.

What the recovery looked like

Before the audit, a 39-day sending blackout with the revenue flows sitting in Draft had collapsed flow revenue by roughly 98.9%.

After the fixes, with four flows genuinely live, seven-day flow revenue came back to about $15.8K:

  • Cart reminder: ~$9.1K (~$212 per recipient)
  • Checkout reminder: ~$3.6K (~$80 per recipient)
  • Browse abandonment: ~$3.0K (~$109 per recipient)

The go-live checklist that prevents most of this

Turning a flow "on" is more than one switch, and this is where people get burned:

  • Flip the flow to Live.
  • Flip each message inside the flow to Live. A live flow full of draft messages sends nothing. This is the single most common cause of "we turned it on and nothing happened."
  • Pause Shopify's native abandoned-cart automations in the same sitting, or every customer gets two emails.
  • Verify the conversion metric on every flow.
  • Verify coupons are attached as dynamic objects, not typed text.
  • Verify links resolve to the customer-facing domain.
  • Trigger each flow with a real event on the live store and read the email that arrives.
  • Check the trigger list matches the list your forms actually write to.

What is still missing on most accounts

The D2C side had Welcome, Browse Abandonment, Abandoned Cart and Abandoned Checkout — and no Post Purchase and no Winback. The wholesale account was missing Browse Abandonment, Abandoned Cart, Abandoned Checkout and Winback entirely.

Post-purchase and winback are the two flows that turn a first order into a customer. They are also the two that get built last, because they do not have the urgency of a cart reminder. Build them anyway.


I audit and rebuild Klaviyo flows on stores where email is a real revenue line. See [Klaviyo expert services](/klaviyo-expert) or [hire a Shopify developer](/hire-shopify-developer).

Direct: [WhatsApp +55 11 98851-2788](https://wa.me/5511988512788) · [contato.matheusabrahao@gmail.com](mailto:contato.matheusabrahao@gmail.com)

Need a senior engineer who thinks like an operator?

I take on a small number of Shopify operations and senior engineering engagements each quarter. If your store needs catalog hygiene, technical SEO, performance, or marketing automation done right — let's talk.

Continue reading

Vamos conversar