Design the unhappy path before launch: the drink nobody picked up

Launch checklists cover the happy path. Your support inbox lives in the unhappy one. How we designed cancel, flag and abandon for drink orders at hopps, and the template I use for any MVP.

Guill Trujillo · 5 min read

This week's Build Notes is about how to plan edge cases before launching an MVP: one feature, the decision behind it, and the artifact I'd hand any founder.

Most launch checklists, including the one I published on Tuesday, are about the happy path. But your support inbox lives in the cases nobody designed: the order that never completes, the invite that sits unopened, the payment someone wants back.

So design the unhappy path on purpose, as a lifecycle, before launch. Here's how we did it for a drink order.

Short answer: To plan edge cases before launching an MVP, list every state a core record can end in, not just the one you designed for. For each state, decide what triggers it, what each person sees and whether it can be undone. Put a timer on anything that can stall, and write the rest down as non-goals.

The situation

hopps, the company I co-founded and ran as Head of Product, let patrons at bars and venues order and pay from their phones while bartenders worked the orders from a pipeline in a venue app. We raised $1.1M, passed $1M in ARR and crossed 50,000 downloads.

The happy path is one line: the patron orders, the bartender starts it, marks it ready, and the patron picks it up. A busy night at a bar is everything else. A patron changes their mind. A bartender can't make what was ordered. An order sits in the queue because nobody saw it. A drink sits on the bar because the patron wandered off.

The decision: every way an order can end is a state

We made each of those its own state in the order model, with rules for who can move an order there and what happens when it does. Four calls mattered most.

  • Price the exit by the work done. A patron can cancel for free while the order is still open. Once the bartender has started it, cancelling costs a fee, and any line-skip fee they paid comes back. Take-out orders can't be cancelled at all.
  • Let the bartender say no. A bartender can flag a started order and take it out of the pipeline. The patron pays nothing for a flagged order, and both sides get a notification.
  • Put a timer on the quiet failures. If nobody starts an order within its estimated wait (five minutes when there's no estimate), the bartenders get a nudge that it's waiting.
  • Make "abandoned" recoverable. At walk-up venues, a drink marked ready that nobody collects within two minutes becomes abandoned. The patron gets a push ("Your drinks miss you!"), the bartenders are notified, our team gets a Slack alert, and it's logged as an analytics event. But the bartender can still complete the order if the patron turns up, so abandoned is a flag, not a dead end. Table-service and take-out orders never auto-abandon.

None of these are features anyone asked for in a demo. All of them are things a bar runs into every night.

The artifact: a lifecycle map

Here's the order lifecycle from the backend's state diagram, in words:

  1. Open → started → ready → completed. The happy path.
  2. Open or started → cancelled. The patron's exit: free until work starts, a fee after.
  3. Started → flagged. The bartender's exit. The patron pays nothing.
  4. Ready → abandoned. Two minutes unclaimed at a walk-up bar. The bartender can still complete it.

The generic version works for any record that moves through states: an order, a booking, an invite, a payout. For each state, answer six questions:

  • What triggers it: the user, the other party, a timer or the system?
  • What does each person see, and what are they told?
  • What happens to the money or the inventory?
  • Can it be undone, and by whom?
  • What does support see when someone calls about it?
  • Is it in scope for launch, or a written non-goal?

If you can't answer all six for a state, it isn't designed yet. It will get designed later, by whoever's on support that day.

What I'd tell a founder

  • List the end states, not just the flows. Every way a record can end is an item on your edge-case backlog.
  • Give every waiting state a timer and an owner. An order nobody starts and a drink nobody collects are silent failures until something pings a person.
  • Make end states recoverable where you can. An abandoned order that can still be completed costs little to build and keeps a slow pickup from becoming a final outcome.

Frequently asked questions

What is an unhappy path in product design?

Any route where the user doesn't reach the intended outcome: a payment that fails, an invite that expires, an order that's cancelled. Designing it means deciding what happens and what each person sees, instead of leaving it to error messages.

How do you find edge cases before launch?

Map every state a core record can be in and every way it can end, then turn each state into acceptance criteria and UAT scenarios alongside the happy path.

Should an MVP handle every edge case?

No. It should handle the ones that cost money or trust, and list the rest as explicit non-goals, so they're decisions rather than surprises.

The takeaway

The happy path gets designed by default. Design the unhappy one before launch, while the cost is a document instead of a support queue.

Planning a launch and not sure what your unhappy paths look like? Book a 30-minute call below and we'll map the lifecycle together.

Product ManagementMVP

Want help applying this? Let's talk.

A 30-minute call about where your product is and what to do next.

Book a 30-min call