The redesign was going well. I had changed the way an approval flow builds its email: instead of an auto-generated HTML table — one of those grey tables nobody reads — each order became a card with its own header, line counter and house formatting.

To do that, the Select action moved from table mode to text mode, producing each card's HTML directly. That left the old Create HTML table action with nothing to do. And here is the decision that cost me a morning: I didn't delete it. I left it there, orphaned, reasoning that if the change had to be reverted, keeping it in place made the rollback cheaper.

What happened

The 13:09 run picked up six real orders and stopped with this error:

The property 'columns' must be specified unless the 'from' property
value is an array of objects.

Create HTML table was still running. With Select in text mode, its input was no longer a collection of objects, so it failed. And because the Compose action after it had a runAfter pointing at it, the whole chain stopped right there.

Result: six real orders with no notification email.

The ugly part

The damage wasn't just the email that never went out. Because of a design flaw that predated my change, that flow marks orders as "Awaiting approval" before it builds and sends the email. So the six orders were flagged as notified without anyone having been notified — and dropped out of the "Pending" filter for good.

A failure in my change turned into data loss thanks to a fragility that was already there.

That's the pattern I see most often: the new mistake breaks nothing on its own; what breaks is how it leans on something that was already wrong.

Three lessons

An orphaned action is not a harmless action. In Power Automate every action runs unless its runAfter says otherwise, and the runAfter of the actions downstream may still point at it. Disabling it is not the same as taking it out of the graph: as long as something depends on it, it's part of the chain.

"Just in case" is not a rollback plan. A rollback plan is the literal content of the fields you're about to touch, stored outside the tool, plus the instructions for pasting it back. Leaving leftovers inside the flow isn't caution, it's setting a trap.

Mark the state at the end, not at the start. If a process writes "already notified" before the notification goes out, any later failure becomes a silent loss.

The right order is: send, verify, and only then mark.

What changed since

This is how I work now: every step of a long edit is saved separately, with a version note, so I can say exactly which one broke something; the original content of every field I touch is copied outside before I touch it; and actions that stop making sense are deleted in the same change that makes them pointless, reconnecting whatever runAfter pointed at them.

The six orders were restored one by one with their original quantities, recovered from each item's version history. It cost a morning. The underlying fix — moving the status write to after the send — went into the plan as what it was: not an extra, but the real reason a ten-minute failure cost half a day.

6 ordersrestored one by one
10 minutesof failure in production
half a dayof real cost