Historical orders replay
Sometimes an order was placed before you created its BOM — the webhook arrived, but with nothing to consume, Assemblified just logged it as no BOM needed and moved on. Historical orders replay lets you fix that retroactively: select past orders, push them back through the same execution pipeline a live webhook uses, and produce a real execution log + inventory delta.
It also covers a few adjacent cases — re-running an order after fixing a recipe, recovering from a transient failure, or backfilling orders that pre-date the app install.
On this page
Section titled “On this page”- Where to find it
- How replay works under the hood
- Picking orders — the two input modes
- Eligibility — what’s blocked, what’s eligible
- The force re-run override
- Multi-location safeguard
- What replays don’t do
- Auditing replays
Where to find it
Section titled “Where to find it”Settings → Historical Orders. A dedicated tab in the app’s settings page. Available to all shops.
How replay works
Section titled “How replay works”A replay is not a fake webhook — it’s a real message on the same queue your live ORDERS_UPDATED events flow through. The pipeline reuses every step described in the execution model:
- You select orders in the Historical Orders tab.
- Assemblified fetches each order from Shopify (line items, fulfillments, cancellation state).
- A queue message is built per order with
webhookTopic = HISTORICAL_ORDER_REPLAY. The message is routed through the BOM execution path internally. - The standard pipeline runs. Pre-assembled drawdown, sub-assembly expansion, raw-material decrement, dynamic adjustment cascade — identical to a live order.
- An execution log rowBOM execution logThe audit trail for one BOM execution — one row per order webhook → DO → Shopify cycle. Captures webhook receipt timestamps, queue lifecycle, DO execution, BOM processing metadata, calculated material changes, Shopify sync status, dynamic-adjustment results, refund history, and pre-assembled consumption. Surfaced in the BOM detail page.
Read more →
is written. Its
webhookTopicisHISTORICAL_ORDER_REPLAY, so you can distinguish replays from live executions when auditing.
Because everything downstream of “message in the queue” is identical to the live path, anything your live executions do, replays will do too — Logistified sync, metafield writes, dynamic adjustment, the lot. There’s no special path for historical orders.
Picking orders
Section titled “Picking orders”Two input modes are available — pick whichever fits the size of your batch.
Visual picker
Section titled “Visual picker”Opens a Shopify-side order browser with search and fulfillment-status filters. Multi-select up to 100 orders per submission and confirm. Eligibility for the selected orders is checked immediately and shown as a badge per row.
Paste or upload
Section titled “Paste or upload”For larger backfills, paste a list of order names (one per line) or upload a CSV with order numbers in the first column. Assemblified resolves the names → IDs against Shopify, shows you which couldn’t be matched, and then runs the same eligibility check as the visual picker.
Either path lands in the same eligibility table. You confirm there before anything is enqueued.
Eligibility
Section titled “Eligibility”Before you submit, each selected order is classified into one of five states. The classification looks at the order’s prior execution history in bom_execution_log and processed_events:
| Badge | Meaning | Default behavior |
|---|---|---|
| Eligible | No prior log — order has never been seen by Assemblified. Most common for pre-install orders. | Replays. |
| Captured (no BOM at time) | A prior log exists but the BOM didn’t exist when the order arrived. This is the primary backfill case. | Replays. |
| Already executed | A prior log shows the create path ran and a BOM was consumed. | Blocked by default. Force re-run overrides. |
| In progress | A processed_events row is still in flight (live order currently executing, or a stuck replay). | Blocked by default. Force re-run overrides. |
| Not seen | No log and no event for this order — same as Eligible, different code path. | Replays. |
The eligibility check is the same logic enforced both client-side (so blocked rows are visibly excluded from the submission) and server-side (so direct API callers can’t bypass).
The force re-run override
Section titled “The force re-run override”A switch in the Historical Orders tab. When on:
- Already-executed orders replay anyway.
- In-progress orders replay anyway.
- Cancelled orders replay anyway.
- Quantity comes from
lineItems.quantity(the original total, including any refunded/removed units) instead ofcurrentQuantity.
Use it when you know what you’re doing — re-running after a manual fix, recovering a failed batch, replaying a cancelled order whose inventory you want back. Inventory will be decremented again, so check the math first.
Multi-location safeguard
Section titled “Multi-location safeguard”If your shop runs location-sensitive dynamic adjustments, replay needs a location to draw inventory from. Live orders get this from the FULFILLMENTS_CREATE webhook, but a historical order may not have been fulfilled yet.
Behavior:
- Order has at least one fulfillment → replay uses
fulfillments[0].location.id. - Order has no fulfillment → blocked with badge Unfulfilled (multi-location enabled). Force re-run cannot override this — it’s a correctness guard, not a duplicate guard.
Fulfill the order in Shopify first, or turn off location-sensitive adjustments in settings, then retry.
What replays don’t do
Section titled “What replays don’t do”Replays only run the create path. They never replay:
- Cancellations. A
cancelled_atorder with force re-run off is skipped (badgeCancelled). With force re-run on, it runs the create path — it does not run the cancel path and does not restore inventory. - Refunds. Refund line items are not replayed. Force re-run uses
lineItems.quantity(the full original) regardless of refund history. The original create’srefundHistorywas captured in its own log row. - Edits. Subsequent order edits are not replayed.
If you need the cancel or refund side of an order replayed too, that’s a separate manual flow — historical orders is scoped to the create path only.
Auditing replays
Section titled “Auditing replays”Every replay writes a bom_execution_log row with webhookTopic = "HISTORICAL_ORDER_REPLAY". Filter the execution-log view (or query the DO directly) on that topic to see exactly what was replayed and when.
For dedup:
- Non-force replays insert a
processed_eventsrow with a syntheticshopifyEventIdof the formhistorical-{orderId}-{uuid}. This dedupes the queue message itself across retries. - Force replays skip the
processed_eventsregistration entirely (shopifyEventIdis omitted). That’s how the override works — and it’s why force replays leave no message-level dedup trail.
The order-level “has this been executed before?” decision lives in the eligibility check, not in processed_events.
Common failure modes
Section titled “Common failure modes”| Symptom | Likely cause |
|---|---|
| Order shows Already executed even though I think it wasn’t | A prior webhook did run successfully (look in bom_execution_log for the order, status inventory_sync_completed). If you want it to run again anyway, flip Force re-run. |
| Unfulfilled (multi-location enabled) badge, can’t override | Multi-location is on and there’s no fulfillment to source from. Fulfill in Shopify first or disable location-sensitive adjustments. |
| Eligibility check fails entirely | Network or DO error — the table will clear and surface the error. Retry; your selection is preserved. |
Replay succeeded but a row landed in Skipped with queue_send_failed | Transient enqueue failure. Re-submit just that order. |
| Force re-run done; inventory looks doubled | Expected. Force re-run intentionally re-decrements. Use a manual inventory adjustment to correct. |
Where to next
Section titled “Where to next”- BOM execution model — the pipeline replays run through.
- Refunds & cancellations — why replays only cover the create path.
- BOM execution end-to-end guide — a worked walkthrough of one live order, useful context for what a replay re-creates.