Implementation worksheet · 6 min read
A Product Demo Script That Shows Failure Recovery
Script the demo so several beats show the app handling something going wrong, because anyone who has bought software knows the happy path is the easy part. Choose failures the app genuinely recovers from on the build you are showing: an input error that keeps the user's work, a permission refusal, a double submit that creates one record, a declined payment in the provider's test mode, and a notification that reaches the right people. For each beat, write what you do, what the audience should see, the fixture it needs and your fallback if the environment misbehaves. Never stage a failure the app doesn't really handle.
Scope: the actor is a founder or seller demoing an AI-built app to a prospective customer, a client at sign-off, or an investor. The starting state is a deployed build that matches production, running on synthetic data and provider test modes, with its recovery behaviours verified in tests or a traceability matrix. The boundary is a live walkthrough; an edited video is out of scope because the audience can't tell what was cut. The outcome is a rehearsed script whose every beat is backed by a test on the same build.
Put it into practice
1. Pick failures from your evidence, not your hopes
Take recovery behaviours that passed on the build you will show: rows in the traceability matrix or entries in a test log. If 'failed payment offers a retry' was last verified three builds ago, re-test it or leave it out.
2. Open with one quick happy path
Run the main workflow once, cleanly, so the audience knows what normal looks like. Keep it short; they have seen happy paths from every vendor.
3. Show an input error that keeps the user's work
Submit a form with two mistakes. Both errors should be named, the valid fields still filled in, and the corrected submission should succeed. It takes a minute and shows the app was built for people who make mistakes.
4. Show a permission refusal from the other side
Sign in as a second role in a separate browser profile and open something the first role owns. A clear refusal, or a not-found page that reveals nothing, shows that permissions exist beyond hidden buttons.
5. Show the duplicate that didn't happen
Double-click submit, or refresh straight after submitting. There should be one record, not two. For webhooks, describe your duplicate-delivery test and show its result rather than trying to reproduce it live.
6. Show an external failure in test mode
Use the payment provider's test mode with a card number the provider documents for declines (Stripe, for example, lists generic and specific decline cards in its testing documentation, as of September 2026). The audience should see a message they could act on and no half-finished state. Check the provider's current test-card list before the demo, since it can change.
7. Write a fallback for every beat
Live demos fail for reasons that have nothing to do with the app: network, an expired session, a sandbox outage. For each beat write a one-line fallback, such as a recording from that morning's rehearsal on the same build, and say plainly which parts are live and which are recorded.
8. Worked example (illustrative, synthetic data)
A fictional room-booking app shown to a coworking operator in about twelve minutes. Beat 1: a member books a free room. Beat 2: a second member tries an overlapping slot; the refusal names the existing booking and the form keeps the chosen room and date. Beat 3: a guest opens another member's booking link and gets a not-found page. Beat 4: a member cancels inside 24 hours, the late fee is charged with the documented decline test card, the booking stays cancelled and the fee shows as unpaid with a retry link, flagged for the admin. Beat 5: the admin blocks a room for maintenance and three affected members' emails appear in the test inbox. Beat 6: one stated limit, then questions. Fixtures: 3 rooms, 9 members, three bookings in room B next week, a guest link and the decline card.
Failure-recovery demo script
Copy this structure into your review document and record your observed result for each row.
| Beat | What you do | What the audience should see | Fixture needed | Fallback if the environment misbehaves |
|---|---|---|---|---|
| Happy path | Book a free room as a member | Booking confirmed and listed | Member account and a free slot | Use the second prepared slot |
| Input error | Submit with a past date and no room | Both errors named; other fields kept | None | Show the rehearsal screenshot of the error state |
| Conflict | Book an overlapping slot as another member | Refusal naming the existing booking | A pre-seeded booking | Show the acceptance test result for the rule |
| Permission | Open another member's booking as a guest | Not-found page; nothing revealed | Guest link and a second booking ID | Show the two-account test result |
| Double submit | Double-click Confirm | One booking created | A free slot | Show the bookings table afterwards |
| External failure | Trigger a late-cancellation fee with a decline test card | Clear message; fee unpaid; retry offered | Provider test mode and a documented decline card | Recording from rehearsal on the same build |
| Notification | Block a room for maintenance | Affected members' emails in the test inbox | Three bookings next week in that room | Show the test inbox from rehearsal |
| Known limit | State one thing the app doesn't do yet | A plain statement of the limit and its workaround | The prototype's limits document | None needed |
A failure worth checking
The staged failure. To make a recovery beat reliable, someone hard-codes a friendly error to appear for the demo account. The buyer sees graceful recovery; the real app shows a blank screen on the same failure. When that comes out, and a pilot is exactly where it would, every other beat in the demo loses its value too. Show only behaviour the build you are running actually has. The counterexample in the other direction: a demo made mostly of failures reads as defensive. Keep the happy path first and the recovery beats short; the point is that recovery exists, not that things break.
Common questions
Isn't it risky to show failures live?
Less risky than being asked 'what happens if the payment fails?' with no prepared answer. The fallback column covers the times the demo environment misbehaves, and saying plainly that a beat is recorded is better than letting the audience assume it is live.
If I can only show two failure beats, which ones?
The two closest to the buyer's money or data, such as the declined payment and the permission refusal. Input errors are reassuring but expected; money and access are what a buyer's technical reviewer asks about.
Should the demo run on production?
No. Use a build that matches production but runs on synthetic data and provider test modes, and say which build it is. A demo on production risks real charges, real emails and real customer data on screen.
Basis and scope
This is a proposed implementation method using illustrative examples, not a measured benchmark or a customer case study. Prepared with AI assistance. Validate product-specific behavior against current documentation and your own test environment.