Turning Complex Problems Into Confident Technology

Bulk-editing a live mailbox without breaking it

Integrating other people's systems · Production · Inside the Workshop

The problem

Years of automated rules had left a shared mailbox with categories applied inconsistently — some by flows that no longer exist, some by rules nobody remembers writing. The categories drive routing, so the mess was not cosmetic. Cleaning it up means a bulk mutation across a live mailbox that people are actively working in.

There is no undo.

Why it mattered

A bulk edit that goes wrong on a mailbox is not like a bad database migration, where you restore a backup and lose an hour. The mailbox is somebody's working surface, the damage is immediately visible to them, and "we will fix it shortly" is not reassuring when the thing that broke is where their work arrives.

What I chose, and why

Two modes, built in order, with the second reusing the first's proven mutation path.

  • Preview mode first. It walks exactly the same selection logic and produces exactly the report the real run would produce, and changes nothing. Not a dry-run flag bolted onto a mutating flow — the reporting path is the one that gets built and trusted first.
  • Apply mode second, reusing the preview's selection wholesale, so the thing that was reviewed is the thing that runs.
  • A safety cap on the number of items a single run may touch. If a selection bug makes the flow believe it should modify everything, the cap turns a disaster into an obvious anomaly. It was later raised deliberately for one specific operation, which is the right way for a cap to change: by decision, for a named case.
  • Live enablement only on an explicit go-ahead. The dry-run switch came off as its own change, on the day, on a person's say-so — not as a default that shipped quietly with something else.

The results of the live runs were recorded: seven of eight confirmed. Not eight of eight, and writing down the one that was not confirmed is the point of writing any of it down.

What the platform charged for this

Most of the difficulty was not the design. It was the low-code platform's own edges, and they are worth naming because they are invisible until you hit them:

  • Every action needs a name that is unique across the whole flow, not merely within its branch — so two branches of a switch cannot both have a step called "Get items".
  • Variable initialisation must sit at the top level of the flow. Nested inside a condition it is accepted by the editor and rejected on import.
  • Whether a connection is embedded in the solution or resolved from the importing user is a per-connection decision that determines whether the import succeeds at all, and the correct answer differed between two connections in the same solution. Establishing that took several attempts in both directions.

None of this is in the reasoning about the mailbox. All of it is in the cost of the work.

What I would do differently

I would put a real reporting path in earlier. An early version of the preview reported a column of categories that was always empty — the report looked right, the data behind it was not there, and a preview whose output is subtly fictional is worse than no preview, because it launders a guess into a confirmation.

I would also be more sceptical of low-code for anything with a mutation cap and an audit requirement. It was the right choice here because the surrounding estate is already in that platform, but a great deal of the effort went into fighting the authoring model rather than the problem.

Related

If this is your problem too

Inherited automation nobody owns is a common finding during a diagnosis. The same mailbox estate is behind the shared mailbox digest, and the wider subject is operational systems.