Your app sends a request. The screen spins. Eventually, it says something went wrong.
Did the action fail, or did the answer fail to reach you?
Those are different problems. If you ask AI to fix both with “just retry,” you can turn one uncertain result into two very certain mistakes.
On September 11, Cloudflare introduced automatic remediation policies for CASB, its service for finding security risks in connected business applications. Customers can configure a matching finding to trigger a remediation action, a webhook, or both. Examples include removing risky file sharing and forwarding an event to another system.
Cloudflare describes a pipeline that passes findings through Queues, checks the configured policy, and runs remediation jobs through Workflows. The workflow machinery preserves progress across interruptions and can back off when another service rate-limits it.
That is useful automation. It also raises a question I want beginners to ask about their own apps: what happens when the same action gets another attempt?
Cloudflare's Queues documentation says a message can occasionally arrive more than once. Reliable delivery still leaves the application responsible for handling duplicates.
My lesson from this release is a practical one: define what “the same job” means before you automate another attempt. You do not need to adopt Cloudflare's stack to use that rule.
If you need help describing your first app's workflow, my free AI App Builder Starter Prompts give you a guided starting point. Then use the checklist below on one action that changes something outside the current screen.
A small example with an awkward failure
Imagine a fictional appointment app. A customer books a session. Your app saves the booking and asks an email service to send the confirmation.
The email service accepts the message. Before your app records that success, the connection drops.
Your app sees a timeout. The customer may already have the email.
Running the whole booking flow again could create another booking and another message. Disabling the button after the first click helps with accidental taps, but it does not solve a restarted background job or two workers processing the same event.
The engineering term you will meet here is idempotency: repeating an operation has no additional effect beyond the first successful operation. I would explain it to a beginner as “another attempt at the same request should preserve the same result.”
Here is the checklist I would give an AI coding tool before approving automatic retries.
1. Name the action you intend to repeat
“Finish booking” is too broad if it includes creating a record, reserving a slot, and sending an email.
Write down each action separately. In this example, retrying a confirmation should not create a second appointment.
Cloudflare's Workflows guidance treats steps as individually retryable and recommends making their calls idempotent. It also warns that effects placed outside steps can repeat when execution restarts.
My application of that guidance: draw the retry boundary around one understandable effect. Avoid hiding several unrelated changes behind a reassuring function name.
2. Keep one request identity across attempts
Give the intended confirmation a stable identifier before the first send. Save it so an app restart does not invent a new one.
For our fictional app, that might identify the confirmation for booking B-104, revision 1. Attempt two keeps that identity. A newly requested confirmation after a genuine reschedule can have a different identity.
The identifier should distinguish the intended action, not merely describe the customer. A customer can legitimately book twice.
The AWS Builders' Library explains how caller-provided request identifiers help a service distinguish a repeat attempt from another legitimate request. It also discusses rejecting changed parameters under an already-used identifier.
3. Enforce the rule where the effect happens
A local note saying “already sent” is useful, but it cannot undo an email service accepting the same send twice.
If the destination supports an idempotency key, send the same key on each attempt and check its documented scope and retention period. If you retry after that protection expires, an old key may no longer protect you.
For a record your own app creates, use storage rules that prevent two concurrent attempts from both creating the same logical result. Ask AI to explain what happens if two workers check for an existing record at precisely the same moment.
“Check, then insert” needs stronger coordination when both workers can pass the check. AWS's discussion of atomic operations is useful here: recording the request identity and performing the associated mutation must not leave a gap that defeats duplicate protection.
4. Give uncertainty its own state
Use states that reflect what you actually know: pending, confirmed, failed, or needs checking.
In our email example, a timeout after submission belongs in needs checking until the app can reconcile the outcome. It should not automatically become “nothing happened.”
Where supported, use the destination's request identity or receipt to check the existing result. If the provider has no duplicate protection and no reliable lookup, some uncertain sends may need human review.
That is a limitation to design around. A retry loop cannot manufacture a guarantee the destination does not offer.
5. Retry for a reason, with an end
A temporary connection problem may justify another attempt once duplicate handling is in place. A rejected address needs correction. Repeating unchanged invalid input mostly creates a louder version of the same failure.
I would write down which errors can retry, the delay between attempts, the maximum attempts, and who sees the job when it stops. Respect the destination's retry guidance and rate limits.
For our booking example, finishing the booking and resolving the email outcome remain separate responsibilities. A delayed message should not silently erase a valid reservation.
6. Test the moment after success
Most beginner tests cover “the request failed before doing anything.” I would add these cases in a disposable test environment:
- Deliver the same event twice. Count the resulting bookings and messages.
- Start two attempts together. Confirm they converge on one intended result.
- Let the destination accept the action, then interrupt the response or local success recording. Check how the app resolves the uncertainty.
- Restart the app between attempts. Confirm the request identity survives.
- Reuse an identity with changed input. Confirm the app rejects the mismatch.
- Make a genuinely new request. Confirm duplicate protection does not suppress it.
These tests expose a particular kind of correctness: the app must remember the difference between trying again and asking for something new.
7. Make the recovery understandable
The person operating the app should be able to see the intended action, its stable identifier, the attempts, the last known result, and the next allowed step.
Keep this record narrow. You usually need an action ID and status, not a copy of the customer's entire message or profile.
I would ask AI to explain one interrupted job from that record. If the explanation depends on guessing whether an external action happened, the recovery path still needs work.
A prompt you can use today
Try this on one workflow:
Inspect the confirmation workflow in this project. List its separate effects. For each, identify the stable request ID, where duplicate protection is enforced, what happens under concurrent attempts, and how an uncertain outcome is reconciled. Distinguish a retry from a new user request. Propose the smallest change and a test that interrupts execution after the destination accepts the action but before local success is recorded. Do not add infrastructure until you explain why the current stack cannot support the requirement.
That final sentence matters. A simple app may handle its needs with its current storage and a provider's existing duplicate protection. More machinery also means more state to understand and maintain.
Start by choosing one external action and writing down what a second attempt is allowed to do. The free AI App Builder Starter Prompts help you turn that question into a guided build conversation. My $9 AI App Builder From Zero e-book provides the organized path from idea through building, QA, and publication.
If you need help turning an idea into a specific project, explore Review Radar's examples and current availability. Its public-review research, tailored screen designs, and AI-ready project folder help define what you will build and how you will test it. You still need to implement and verify the behavior behind those screens; the package does not promise a finished app or revenue.
Before you tell AI to try again, make sure your app can recognize what it already tried.
You can also find me here:
Medium: https://medium.com/@marcusykim
DEV.to: https://dev.to/marcusykim
Website: https://marcusykim.com/
X: https://x.com/marcusykim
LinkedIn: https://www.linkedin.com/in/marcusykim/
Upwork: https://www.upwork.com/freelancers/marcusykim
Top comments (0)