AFL engineering workbooks · For developers building AI agents

When the Agent Acts Twice

Learn to catch duplicate actions before you approve an agent’s retry logic.

An agent retries an $80 refund after a timeout. The retry succeeds. You still don’t know whether the customer was refunded once or twice.

This workbook puts you in the code review. You’ll inspect the evidence, reproduce a duplicate refund, and test a repair that keeps each retry tied to the original approval.

Get the free workbook and JavaScript lab →

ZIP download. No signup. Runs locally with Node.js 22 or newer.

The mistake starts with a reasonable assumption

A teammate adds a retry because refund requests sometimes time out. Their explanation sounds sensible: if the request failed, give it another chance.

But a timeout only tells you that the client didn’t receive a response. The service may already have issued the refund. Sending another request with a new key can issue another one.

Here’s the trace you receive in the review:

operation R-101, key afl-refund:R-101:attempt-1
timeout: no usable response
operation R-101, key afl-refund:R-101:attempt-2
response: refund RF-0002, succeeded

You have approval for one refund and a record of two attempts. Your first job is to decide what evidence would establish how many refunds actually happened. Write that down before opening the lab’s refund records.

What you’ll practice

  • Distinguish a request that never took effect from an action that completed but lost its response.
  • Write a regression test that catches a second refund for the same approved operation.
  • Keep the operation’s identity stable across retries and process restarts.
  • Check what happens when a repeated request changes the amount or arrives alongside another retry.
  • Make a release decision that names the evidence you have and the guarantees you still need.

A workbook you can work through in code

Start with the review packet and write your diagnosis. Then run the faulty implementation, inspect the refund records, and write the check that should fail. Compare your proposed fix with the repaired code after you’ve made your own decision.

  • A seven-part workbook covering the investigation, repair and release decision, with a final shipping-label exercise.
  • A separate answer key with the reasoning behind each decision.
  • A JavaScript lab with faulty and repaired implementations and 13 automated tests.
  • A reusable review worksheet for your next change to a workflow that takes external actions.

Start with the failure

Download and unzip the package. Open WORKBOOK.md and follow the exercises. When you reach the lab, run this command from the extracted folder:

node lab/run.mjs faulty

You need Node.js 22 or newer. There are no dependencies to install, API keys to supply, or services to configure. The exercise uses synthetic data, runs offline and makes no real payments.

The lab documents the assumptions behind its simulated refund service. Before applying the repair to a real integration, check how your provider handles repeated requests, how long it retains request keys, and how you can look up an uncertain result.

Bring the review back to your own system

Use the agent launch checklist to review permissions, costs and release checks around the workflow. If the agent runs on AWS, the iam:PassRole walkthrough and free IAM skill give you a starting point for reviewing its access.

After trying the workbook, tell me which part changed how you would review the retry. If a step was confusing, I’d like to hear that too.