Picture a trip-planning tool where a traveler can drag an activity to a new time slot. It's a simple interaction on the surface: pick up a card, drop it somewhere else on the day. But the moment you let people move things freely, you inherit a harder problem: what happens when the new time slot isn't actually free?
The tempting answer is a single conflict dialog. Something moved, something else is now in the way, show a warning, offer "Override" and "Cancel," done. I've seen that shipped more than once, and it always breaks down the same way: the first real conflict a user hits doesn't match the two buttons on offer, because "conflict" was never one problem to begin with.
A moved activity can collide with the rest of a schedule in a handful of genuinely different ways, and each one calls for its own resolution, not a shared modal that happens to fit none of them well. The design work isn't writing a clever conflict dialog. It's naming every distinct way the collision can happen, before designing anything.
The mild case: partial overlap
The most common case is also the gentlest: a moved activity bleeds into the start or end of the one next to it. A dinner reservation creeps twenty minutes into a walking tour. Here the traveler has real, low-stakes options: nudge the neighboring activity to make room, trim the moved one to fit, let both sit there with the overlap flagged for later, or back out entirely. Four choices, and every one of them is reversible and low-consequence. This is the case a lot of teams design for first, and then quietly assume it covers everything else.
The case that erases something: full overlap and cascades
Two other shapes get more serious. A moved activity can fully swallow a smaller one already there, a three-hour excursion landing right on top of a thirty-minute lunch. Here the traveler isn't just resizing something, they're deciding whether the smaller activity survives at all. That's a different decision than a partial overlap, and it deserves options that say so: replace the smaller activity outright, keep both and accept the overlap, or cancel the move.
The other serious shape is a cascading conflict: shifting one activity fixes the immediate collision but creates a new one further down the day. Push the tour back an hour, and now it collides with whatever comes after it, and so on. The honest options here are auto-cascading the whole chain by the same delta, or stepping through each collision one at a time so the traveler sees what's happening at every step. Neither should happen silently. A tool that quietly cascades changes across a day without telling anyone is the fastest way to lose a user's trust in the schedule they built.
The case you can't just re-time: a fixed booking
The case that matters most, and the one a generic dialog handles worst, is a conflict with something that can't move: a paid reservation, a ticketed tour, anything with a locked time. Here there's really only one flexible party in the collision, so the resolution isn't a coin flip between two equal options. It's telling the traveler plainly that the thing they're moving is the only thing that can give, then letting them adjust it, accept the overlap, or cancel. Treating a fixed booking the same as two flexible activities is where a generic conflict dialog does real damage, because it implies a choice that doesn't actually exist.
The taxonomy at a glance
| Conflict type | What happened | Options offered |
|---|---|---|
| Partial overlap | Moved activity bleeds into a neighboring one | Nudge neighbor · trim moved activity · allow overlap (flagged) · cancel |
| Full overlap | Moved activity fully swallows a smaller one | Replace the smaller activity · keep both, accept overlap · cancel |
| Cascade | Fixing one collision creates a new one further down the day | Auto-cascade the whole chain · step through each collision one at a time |
| Fixed booking | Collides with something that can't move (paid, ticketed) | Adjust the moved activity · accept the overlap · cancel |
What this isn't
This isn't a complete list, and it isn't meant to be. Two harder shapes sit past what's covered here: a move that pushes an activity across midnight into the next day, and a move that creates several conflicts at once. Both are real, and both deserve their own resolution. For the second one, a summary view that lets someone act on every affected activity at once tends to work better than forcing them through collisions one at a time.
The point isn't to enumerate every possible collision before shipping anything. It's to keep treating "conflict" as a category with real subtypes, and add a new one deliberately when testing surfaces it, rather than folding it into whichever dialog already exists.
What I'd carry forward
A few things worth applying to any tool where one edit can invalidate another:
List the actual ways a conflict can occur before designing how to resolve it. "A conflict happened" is not a specification.
Check that each scenario's options are genuinely different from the others. If two conflict types share the same two buttons, they're probably not two conflict types.
Never resolve anything irreversible without showing the person what's about to happen, even when auto-resolving would be technically correct.
Treat a fixed, unmovable commitment as its own category. It doesn't share options with a conflict between two flexible things, and design that pretends otherwise misleads people.
Closing
None of these resolutions are clever. They're closer to just paying attention: naming what's colliding, saying what will happen, and giving the person a real choice instead of a plausible-looking one. The bar for a good conflict dialog isn't cleverness. It's coverage.