Warehouse Operations

We have a product recall. How do I find every Shopify and wholesale order that shipped a specific lot and freeze the rest?

Finding every order that shipped a recalled lot and freezing what is still on hand.

Last updated September 16, 2026

Shopify tracks the SKU. It does not track the lot unless you bound that lot at receipt and again at pick. A recall on a SKU-only ledger is a spreadsheet of guesses.

Freeze remaining stock first

Freeze first. Quarantine or hold every remaining unit of that lot in every building, including the 3PL, before you write a customer email. If you start in Klaviyo, the next wave ships the rest of the lot while you draft the message. The 3PL does not freeze because you posted a hold in your own warehouse. Send the freeze. Confirm they stopped allocation. Then export.

Export every shipment with the lot

The export is every shipment that consumed that lot, not every order that bought the SKU. Shopify DTC packs, wholesale 856s, Amazon if you sent that lot, and any store transfer that already left. If two lots sat on one pick line, you need the line-level lot, not the order header. If the picker chose from a dropdown, the recorded lot may be wrong. Treat that as a wider net, not a clean list.

Keep lot codes unique

Lot codes must be unique per SKU and per receipt. Reusing LOT-001 across SKUs, or one lot per SKU forever, makes the freeze hit the wrong pile or miss the real one. Do not use the expiry date as the lot code. That shortcut breaks the recall the day two receipts share a date. Once lot control is on, every receive, pick, pack, transfer, and 3PL feed has to carry it.

Do not mix this with serials. A lot is a batch. A serial is one unit. A recall that asks for serials you never captured will stall. You cannot invent a serial list from a lot, and you cannot freeze a lot by asking for serials. Returns of the recalled lot go to quarantine, not back to sellable. Inbound still on the water with that lot must land in hold, not available-to-sell. After the list is out, you can message customers. The list is the work. The email is last. A Klaviyo segment of everyone who bought the SKU is not a lot list. It is a wider net you send only after you admit the trace is missing.

Containment when trace is missing

If the lot was never bound at receipt or at pick, stop and say so. You can freeze remaining on-hand by SKU and date window, then widen the customer list. That is a containment, not a trace. Next inbound, require lot and expiry on the receipt line. A containment you name is better than a fake trace you cannot defend. Marketplace and 3PL nodes each need their own freeze ticket. A hold in your WMS does not stop FBA or a second 3PL from allocating the same lot tonight.

Run this with AI

Connect Claude or ChatGPT to your Fulfil data with the Fulfil MCP, then run this prompt on your own numbers.

You are the ops lead running a lot recall.
Here is: sku, lot, expiry, qty_on_hand, location, 3pl (y/n), receipt_id, shipment_id, channel (shopify / wholesale_856 / other), lot_on_pick (y/n), lot_on_receipt (y/n).
[paste]

Produce:
1. Remaining units to quarantine now, by location, including the 3PL.
2. Every shipment that consumed this lot (not every SKU order).
3. Lines with missing or reused lot codes, or expiry used as the lot.
4. Whether this is a true trace or a SKU-and-date containment.
Freeze first. Do not start with Klaviyo. Lots only, no serials.

See it run on
your data.

Fulfil runs inventory, fulfillment, purchasing, and accounting for scaling DTC brands in one system.