323 messages in three hours: a post-mortem of an auto-reply that went wrong
A weekend acknowledgement told four years of closed conversations “we’ll be back Monday”. Nothing was broken; two safe changes met. What every marketplace automation now checks before it sends.
What happened
On Saturday 1 August 2026, at a UK furniture seller, an out-of-hours acknowledgement started sending. It had run every weekend for months without incident: when a customer wrote outside business hours, it replied in the customer’s language that the team would be back on Monday. That Saturday it sent 323 messages in three hours. Four were right. The other 319 went to conversations that had been closed for months or years; the oldest was from 2022.
No customer had written. No system had failed. Every component did what it was designed to do.
Two harmless changes
The automation’s conditions were: it is out of hours, the last sender in the thread is the customer, and the thread has not been acknowledged before. Reasonable, and for months sufficient, because the thread list it read only ever contained the last few weeks of conversations. The list was short for an accidental reason: a pagination bug stopped it at about 600 threads.
Four days earlier someone fixed the pagination bug. The list grew from 600 threads to 7,481, and a four-year archive of finished conversations, most of them ending with a customer’s “thanks”, entered the loop for the first time. Every one of them was out of hours, customer-last and never acknowledged.
- 1TuesdayPagination fix deployed. Thread list goes from 600 to 7,481. Nobody re-reads the automation's filters.
- 2Saturday 09:00Weekend gap starts. The acknowledgement walks the whole list. Every archived thread passes every check.
- 3Saturday 12:00323 sent. A customer replies to a 2022 thread asking what this is about. Someone notices.
- 4Saturday 12:20Automation switched off by hand. Then the clean-up.
The general pattern
The lesson is not “write more conditions”. It is that a change that widens a data source silently re-exposes every automation that consumes it. Pagination fixes, longer date windows, new channels, a re-sync after an outage: each one makes a list longer, and every filter downstream was written against the shorter list. The automation was never wrong about freshness; it had simply never been asked.
Two design rules follow. Freshness must be checked against the automation’s own last successful run, not only against an absolute age; and “the first import” and “a full re-scan” must be states the automation can see and refuse to act in.
The gates, in order
This is what a Growstall acknowledgement passes now, top to bottom, before it sends. The order matters: the cheap, absolute stops come first.
| Criterion | What it checks | Why |
|---|---|---|
| 1 · Kill switch | Workspace-wide stop is off | One click stops everything; the first thing to press |
| 2 · First import / re-scan | Channel has a previous successful sync and a finished import | An archive entering the loop for the first time never gets a reply |
| 3 · Breaker pause | No pause from an earlier trip today | A person resumes, not the clock |
| 4 · Enabled | Off by default | Opt in after reading the exact text |
| 5 · In a gap | Next business window more than N hours away | Weekends and holidays, not ordinary evenings |
| 6 · Not a system notice | Operator tasks are excluded | "Supplier must contact the customer" is not a customer |
| 7 · Customer last | Thread needs a reply and the customer wrote last | Never after an operator or after ourselves |
| 8 · Not acknowledged before | One per thread, ever | No second courtesy message |
| 9 · After the gap started | Message arrived once the office closed | Never to a message you could have answered on Friday |
| 10 · Younger than 3 days | Absolute age gate | The 2022 threads fail here |
| 11 · Newer than the previous sync | Message arrived after the automation's own last run | A widened list cannot smuggle old-but-recent threads through |
| 12 · Deliverable | A customer with an id and a message body | No sends into the void |
| 13 · Circuit breaker | Fewer than 10 sent this run | Trips, pauses until end of day, notifies a person |
Before the switch is turned on, the system also rehearses: it counts how many threads would pass the rules right now and refuses to enable if the answer is implausible for a fresh weekend. And every send is written to a log with the date of the message it answered, so a drift like the one above is visible as a column of dates, not as a customer’s confused reply.
The response order when it does go wrong
- Stop the bleeding. Kill switch first. Understanding comes after.
- Back up the affected records before touching anything.
- List every wrong send: channel, thread, order, and the date of the message it answered. That list is the incident record.
- Clean the panel: old conversations must not appear as “acknowledged, awaiting a person”.
- Do not send a correction. A second message into a closed 2022 thread confuses the customer more than the first one did. Handle replies by hand.
- Find the widening. What made a list longer in the days before? Re-read every automation downstream of it.
The seller’s weekend acknowledgement is back on, behind the thirteen gates. It has sent to four threads since. All four were customers who had written that morning. Why an acknowledgement matters at all, and how to set one up without a surprise.
- The automation was never wrong about freshness; it had never been asked. Check freshness against your own last run, not only an absolute age.
- A change that widens a source (pagination, window, new channel, re-sync) re-exposes every automation downstream. Re-read their filters.
- Order the gates: kill switch, first import, breaker pause, then the message-level checks, then the per-run ceiling.
- When it goes wrong: stop, back up, list, clean the panel, no correction message, find the widening.
Questions people ask
Is an automatic out-of-hours reply allowed on marketplaces?
On most Mirakl operators, yes, as long as the message contains no links, contact details or marketing, and it is sent as the seller. It does not stop the operator's reply clock. On Amazon Buyer-Seller Messaging automated replies are restricted and Growstall never sends one.
How do you stop an automation from replying to old messages?
Three checks together: the message must be younger than a few days (an absolute age gate), it must have arrived after the automation's own previous successful run (a freshness gate), and the channel must have finished its first import (a scope gate). Then a per-run ceiling that pauses the automation and notifies a person when it trips.
What should you do first when an automation sends the wrong messages?
Stop it: a single workspace-wide kill switch that every automation reads before it acts. Then back up the affected records, list every wrong send with channel, thread, order and the date of the message it answered, clean the panel so old conversations are not shown as awaiting a reply, and do not send a correction message into old closed threads.