There's a strange ritual I've watched play out in automated warehouse projects over the last few years. The WMS vendor and the WES vendor sit around the same conference table. They talk interfaces, they talk hardware, everything's cordial — until someone says "task allocation." Then both sides start looking at each other, the thought readable in their eyes: that's your job.

After the meeting, the client always pulls me aside. "Lao Mi, who actually owns this?" I usually answer with a question of my own: "Is it in your contract?" Nine times out of ten, the answer is no. And that silence is exactly the problem. Wave release, hot picks, exception handling — three jobs nobody wants to claim, and three places where automation projects go to argue.

Wave release: the WMS writes the tune, the WES controls the tempo

The textbook story is clean. The WMS groups orders into waves by priority and carrier cutoff times, releases them one wave at a time, and the WES executes. One side sets the strategy, the other side does the work.

Then AMRs and shuttles showed up, and the story got messy. The WES vendor will tell you they can see every robot's real-time status and every aisle's congestion, so they can build and release waves dynamically, far more efficiently than the WMS's rigid timed releases. The WMS vendor's response: waves are order strategy, they're fulfillment commitments, and no equipment vendor gets to decide those.

I watched this exact fight play out in 2023 at an e-commerce fulfillment center in Southern California's Inland Empire — a building north of 200,000 square feet, forty or fifty AMRs on the floor. The WMS released a wave every 20 minutes based on carrier cutoffs. The WES couldn't keep up: robots were still chewing through the last wave when the next one landed. Pickers stood in the aisles waiting for tasks while robots ran empty. The WMS team said their wave logic was sound; the WES team said the release cadence was impossible. The client sat between them — both sounded reasonable.

Here's my call: wave strategy belongs to the WMS — the grouping rules, the priority logic, that's order management and fulfillment. But release pacing has to be shared with the WES, because only the execution layer knows what the equipment can actually swallow. In practice there's no single owner here, only co-ownership, and it needs to be written into both contracts: the WMS owns wave strategy configuration, the WES owns release pacing, and the interface contract says the WMS publishes waves while the WES publishes its real-time capacity to absorb work. Whose fields, whose logic — on paper.

Pickers and AMRs working side by side in warehouse aisles

Hot picks: the hottest potato in the building

Nobody fights harder than over hot picks: customer service calls, a key account has an emergency order, it has to ship in two hours. The WMS flags it top priority and pushes it to the WES. The WES salesperson promised dynamic prioritization during the demo. At go-live, inserting one order into a sequenced task plan means recalculating routes, and the whole floor's efficiency dips. The WMS says, "I flagged the priority, the rest is yours." The WES says, "You flagged it, but I can't execute it."

In 2024, at a 3PL site in Ohio, peak season brought dozens of hot picks a day, nearly one an hour at the worst. When we dug in, the WES had no dedicated lane for expedited tasks at all. Every hot pick went through the normal re-sequencing queue, the solver got slower and slower, and regular orders got dragged down with them. The client was furious: "That's not what you sold us."

I've boiled the fix down to three non-negotiables: hot-pick authority sits with the WMS — who is allowed to expedite, and how many times a day, because there has to be a quota, and anything over quota goes through manual approval; expediting without a quota is a guaranteed disaster, the WES will be drowned by unlimited interruptions, and that's physics, not a software bug. Hot-pick execution sits with the WES — reserve capacity or build a dedicated lane so expedited tasks don't wreck the global sequence. And the SLA goes in the contract — from the moment a hot pick is issued to the moment execution starts, no more than an agreed number of minutes. The number is negotiable. Having a number is not.

Exception handling: where smart systems play dumb

Third, exceptions. A robot gets stuck, a label won't scan, a weight check fails — the task dies halfway. Who intercepts it? Who decides: retry, or kick it to a human? The WMS vendor's line: "We're the upper system; the WES should handle exceptions first and escalate what it can't." The WES vendor's line: "We run the equipment; business exceptions — like something wrong with the order itself — that's the WMS's call."

Both sound reasonable. In practice, the exceptions neither side claims simply vanish inside the system. On one project, during the first three months after go-live, the WES believed it had reported exceptions the WMS believed it had never received. It took over a week to find the root cause, and it was almost embarrassing: the exception codes the WES was sending didn't exist in the WMS's dictionary, so the interface silently dropped them. A carton sat on a conveyor for two days. Nobody knew.

So exceptions have to be split into two layers. Equipment-layer exceptions — stuck robots, lost connections, failed scans — belong to the WES, which must try to self-heal first: retry, reroute, and only then escalate. Business-layer exceptions — cancelled orders, inventory mismatches — belong to the WMS. And between the two layers there must be a single exception-code mapping table, signed by both vendors and tested line by line during integration. Most projects don't have this table. They test that the interface connects and declare victory. Remember: a connected interface is not the same as a working exception flow.

The real root causes — and how to write them out of existence

By now the root causes are probably clear. But let me name them, because naming them is what makes them contractible.

Start with the fact that nobody has ever defined what a WES actually is. Ten years ago the WMS ran everything and the equipment was dumb. Then AMRs and shuttles grew brains, and the WES was born to manage them. But the industry never standardized the WES boundary — one vendor's WES is practically a small WMS, another's is barely a device scheduler. During selection you think you're buying the same thing from every bidder. You're not. The demos all look alike; the contracts describe two different animals.

Then there's the deeper problem: both sides are "optimizing," but they're optimizing different things. The WMS optimizes fulfillment — on-time rate, cutoff compliance. The WES optimizes equipment efficiency — robot utilization, aisle throughput. Fulfillment wants speed; equipment wants smoothness. They're in tension by nature, and waves, hot picks, and exceptions are exactly where those two objectives collide. So the finger-pointing isn't an attitude problem. The objective functions genuinely disagree.

And the most damaging one: it's not in the contract. The WMS statement of work says "Vendor is responsible for the task allocation module." The WES statement of work says the same sentence. Overlapping boundaries plus vague wording equals a standing invitation to argue.

So how do you write it into the contract? The template I give clients is a simple table with three columns: item, owner, co-owner. It covers at least eight items: wave strategy definition, wave release pacing, hot-pick authority and quotas, hot-pick execution lane, equipment exception self-healing, business exception adjudication, exception-code dictionary maintenance, and interface field ownership. Every item gets exactly one owner. "Support" or "assist" doesn't count as an assignment.

I also insist on a few hard clauses: acceptance criteria spelled out — the exception-code table tested line by line with a 100% pass rate, hot picks going from issuance to execution start in under five minutes, where the number is negotiable but having one isn't. Responsibility for maintaining the exception dictionary assigned to a named person, with any new code synced to the other side within 48 hours. And a tiebreaker clause I added after getting burned a few times and have never removed since: boundary disputes get decided by the client within 48 hours, and neither side gets to stop work while arguing.

Back to that conference room. The next time the WMS vendor and the WES vendor sit down together and start looking at each other over task allocation, I usually interrupt: stop looking, open the contract, find the page and the line. Boundaries don't get settled by arguing in meetings. They get settled by writing. Write them down and both sides know their jobs; leave them vague and every exception, every hot pick becomes a fresh argument. And the cost of all that arguing lands, every time, on the client.