Skip to main content
Exemplar page — first pass. This is a proposal for review, not established policy. The thresholds in TITAN-DESTROY-01 especially are judgment calls that should be checked against real Invoca product flows before adoption.

The problem

A user is about to do something that destroys work: delete a campaign, discard unsaved edits, remove a team member, cancel a running job. Get this wrong in one direction and people lose work they cannot recover. Get it wrong in the other and every routine action grows a modal that users learn to dismiss without reading — which destroys the protection for the cases that actually needed it. The confirmation dialog is not the pattern. The pattern is deciding whether to confirm at all.

Decide first: undo, or confirm?

Undo beats confirmation whenever it is achievable. A confirmation taxes every user every time, including the overwhelming majority who meant to do it. Undo taxes only the user who made a mistake. Building soft-delete so undo is possible is nearly always the better investment over adding a dialog.

When this applies

  • The action is not reversible by the user without contacting support.
  • The action affects objects other people depend on — shared reports, live routing, team access.
  • The action stops something currently running or generating revenue.

When it doesn’t

Structure

The destructive action is never the contained Button. See TITAN-BTN-02. Weight is an invitation. The interface should be easy to escape and deliberate to commit. Severity is carried by the copy and the friction, not by making the dangerous control the most attractive one.
A cascade adds one line to the body — never a second structure. When the object being deleted has dependents, the body states what else is affected, alongside the object’s own consequence:
See TITAN-DESTROY-10.

Three tiers of friction

Match friction to consequence. Using tier 3 everywhere is the same failure as using tier 1 everywhere — it just takes longer to show up.
1

Tier 1 — Undo. No dialog.

Reversible in-session. Perform the action, show a Toast with an Undo action for at least 10 seconds.Removing a filter, archiving a draft, deleting a row from an unsaved table.
2

Tier 2 — Dialog naming the object.

Not user-reversible, recoverable by support. Dialog states the object by name and the consequence in outcomes. Confirm button restates the action.Deleting a saved report, removing a team member, deleting a campaign with history.
3

Tier 3 — Typed confirmation.

Unrecoverable, or affects live traffic, billing, or other people’s work. The user types the object’s name to enable the confirm button.Deleting a workspace, revoking an API key in production, cancelling a running job.
Typed confirmation works because it defeats muscle memory. Its power comes entirely from being rare. Use it in more than a handful of places and users learn to copy-paste, at which point it is friction with no protection.

Behavior

Constraints

Constraints Titan should enforce

Destructive confirmation: open issues

Constraints Titan should enforce for Destructive confirmation.

Content

Do not apologize and do not soften. “We’re sorry, but this will permanently remove…” adds words at the exact moment the user should be reading carefully. State the consequence plainly and stop. Never use “Are you sure?” It asks about the user’s confidence when the useful question is about the outcome. Someone who is sure they selected the right row, but didn’t, answers “yes” correctly and still loses their work. Naming the object is what catches the error.

Accessibility

  • Dialog uses role="dialog" with aria-modal="true"; title is referenced by aria-labelledby.
  • Focus is trapped for the dialog’s lifetime and returns to the triggering control on close.
  • Initial focus lands on Cancel — see TITAN-DESTROY-06.
  • Escape always closes without acting.
  • The consequence text must be in the accessible description, not conveyed by an icon or by red text alone — see TITAN-COLOR-03.
  • Typed confirmation inputs need a visible label stating exactly what to type; do not rely on placeholder text, which disappears on focus.

Variations

Anti-patterns

Confirming everything. The most common failure. Every confirmation reduces the attention paid to the next one. A product where deleting a filter and deleting a workspace both open a dialog has taught users that dialogs are noise. The scary dialog. Red header, warning triangle, contained red button. It reads as severe and behaves as an invitation — the most prominent, most attractive control on screen is the destructive one. Users click the biggest button. “Are you sure?” with Yes/No. Ambiguous at the moment of commitment, and it tests the wrong thing. See TITAN-DESTROY-04. Delete with no undo and no confirmation. Occasionally shipped on the reasoning that the action is “obviously intentional.” Mis-clicks are not intentional, and neither is operating on the wrong row after a sort order changed underneath the user. Confirmation as a substitute for soft delete. A dialog is cheaper to build than recoverable deletion, so it gets chosen. It protects against mis-clicks and not against mistakes — the user who confidently deletes the wrong campaign passes the dialog without hesitating. Where the data matters, build the recovery. A cascade delete whose dialog only names the primary object. The reader discovers what else disappeared only after confirming — see TITAN-DESTROY-10. Treating “orphaned” and “deleted” as the same outcome in the dialog copy. They leave the product in different states, and the reader needs to know which one they’re choosing — see TITAN-DESTROY-11. CRUD overview, for how this pattern is the whole answer to CRUD’s Delete operation — there is no separate Delete page. Bulk selection, which routes into this page’s bulk-destructive variation rather than confirming per row.
Last modified on September 7, 2026