---
title: "Two Texts to One Person After a Crash at the Worst Moment"
canonical: https://dxdev.com/everyday-ai/the-provider-said-yes-before-we-were-actually-done/
datePublished: 2026-06-18
---
The risky moment was the one between a text message going out and our own system writing down that it had gone out.

The idea was simple. When an automated job finishes, send a real text message to a person. A log entry nobody's watching doesn't do that, and neither does a green light in a browser tab that's already closed. A short message that reaches someone even when they've stopped paying attention to the run.

We were building it during a production cutover, which means moving live work from the old setup to the new one. We believed the hard part was already handled. Move the sending duty to the new worker carefully, verify it, and keep the old path listening as backup just in case. That plan solved the problem we were watching for.

It did not occur to us that the messaging queue had its own separate risk underneath. The queue is the thing responsible for carrying that safer version of the send. We only found the risk after sitting with the failure mode long enough to ask a more specific question: what happens if the process handling this crashes at the exact moment between the message going out and our own system recording that it went out?

## Two facts that sound like one

That gap is easy to miss because both halves of it sound like "sent." The outside messaging provider accepting a request is one fact. Our own system finishing its bookkeeping and marking the job complete is a separate fact, a moment later.

Say a crash lands between those two moments and the job retries. From the system's point of view nothing has been recorded yet, so it tries again. The provider accepts the second attempt too. The same message goes out twice, to a real person, for a mistake that only ever happened in the space between two events that felt like they should have been one.

## Why one marker at the end can't fix it

A single marker written only after everything finished wouldn't close that gap, because the crash happens before that marker ever gets written. The fix needed two separate signals:

- A short-lived claim, set before the outside request goes out at all, so a near-simultaneous retry doesn't double up on something already in flight.
- A longer-lived marker, set only after the provider actually confirms it received the message.

Two facts, recorded at two different times, because they are two different events separated by a real window where a crash can land.

## What to check in your own setup

If a process of yours talks to an outside service, look at the space between "the outside service said yes" and "our own system wrote down that this is done." If both happen in one step, with one marker set only at the end, a crash in between can make a retry repeat the exact thing you were trying to make safe. That could be a message resent, a charge run twice or a notification duplicated. Put a marker on each side of that gap, so a retry can tell the difference between "never happened" and "already happened, just not filed yet."
