Liam Croft
Product
Most shipping software treats a stopped order as a failure state to be cleared. We treat it as the product doing its job. This is what changed once we gave every reason a shipment can stop its own name.
The clear-the-queue instinct
Every operations tool we looked at framed exceptions the same way: a red count in the corner, and a button to make the count go down. The implied goal is an empty queue. But an empty queue is not the goal of a shipping operation. Shipping the right parcel, to the right address, at the right declared weight, under the right service, is the goal. The queue is only a measurement of how often those things are in doubt.
When the interface rewards clearing, people clear. They approve past a warning they do not fully understand, because the warning is generic and the pressure is real. Six weeks later somebody is reading a carrier surcharge invoice trying to work out which of four hundred parcels was under-declared, and there is no record of who decided what.
A system that quietly proceeds when it is unsure is not automated. It is unaccountable.
Naming every reason
So we stopped emitting validation errors and started emitting hold reasons. The difference is not cosmetic. An error is a message; a hold reason is a named state with an owner, a resolution path, and a place in the audit record.
// before { "error": "Order failed validation (3 errors)" } // after { "status": "held", "hold_reason": "item_weight_mismatch", "detail": "line 2 declares 2.000 kg; carton scan reports 2.400 kg", "rule": "wt-tolerance-uk", "rule_version": 7, "resolvable_by": ["orders:correct"] }
Once the reason is a value rather than a sentence, everything downstream gets easier. You can filter on it, count it, route it to a person, chart it by SKU, and — the part that mattered most to us — you can write a help article for it that a packer can actually find.
What changed at the bench
The first thing we noticed watching a real packing bench was that nobody wanted fewer holds. They wanted the hold to arrive earlier and to say something specific. A weight discrepancy caught at intake is a two-second fix in a spreadsheet. The same discrepancy caught at the bench is a repacked carton, a reprinted label, and a delayed van.
So the correction flow does not ask the user to fix the order. It asks them to record what is true, with a reason, and then it reruns validation itself. The original capture is never overwritten. If someone later disputes the declared weight, the source value, the corrected value, the person, the reason, and the timestamp are all still there.
The cost of a silent decision
There is a version of this product that ships more parcels per hour than ours does. It guesses. It rounds a missing weight up to a safe default, picks the cheapest service that fits, and moves on. For a long stretch it looks better on every dashboard we could build.
The bill for that arrives later and somewhere else: in surcharges, in customs delays, in a customer who was told the wrong thing, in an operations lead who cannot answer a simple question about what happened. We would rather stop, say why, and let a person decide.
If your team spends its day correcting shipments other software already released, we would like to see your order shapes.
Book a pilotKeep reading
ZeroClickShip
Evidence-first shipping operations for UK ecommerce teams and fulfilment operators.
ZeroClickShip is a shipping operations platform. Carrier services are contracted directly between the merchant and the carrier under the merchant's own accounts. Capability status shown on this site reflects demonstrated, in-source, and roadmap work; provider activation is subject to integration and acceptance testing. © 2026 ZeroClickShip Ltd.