Tell a Coding Agent Whether Retry Means the Same Job or Another One

Drafted and reviewed using AI assistance.

On this page

When an app gives no response, “try again” can mean two different things: recover the result of the request you already made, or ask for another result. Tell a coding agent which meaning you want before asking it to add retries.

The important distinction is the user's intended operation. Matching button clicks or matching inputs alone may not express it. A person can intentionally request two identical jobs; a network retry can repeat one job request without asking for another.

This guide uses an original, fictional preview-job app. The sequences and outcomes below are proposed requirements. They have not been implemented or tested, and do not describe a CueSpec production issue.

Give the operation a small, clear boundary

Imagine an app with built-in color palettes. A user selects coast and small, then chooses Create preview job. The operation creates a draft job record; generating a preview happens later.

For the examples, use these labels:

Object Example What it identifies
Operation create-preview-job The kind of action requested
Namespace board-a The example's scope for request identity
Request ID req-101 One intended creation, including its retries
Meaningful inputs palette=coast; size=small The requested job's settings
Job ID job-17 The record created by that operation

The namespace is an illustrative label, not an access-control design. The implementation still needs to define who may create or recover a job in that scope.

Our proposed contract treats the operation, namespace and request ID together as an identity. Within that identity's supported lifetime, matching retries should recover the original creation rather than make another record.

AWS's engineering article explains why request identifiers can express intent more clearly than deducing duplicates from matching parameters. It also discusses equivalent retry responses, late requests and differing service requirements. Those are design concepts, not a guarantee supplied by every API. AWS: Making retries safe with idempotent APIs

Sequence 1: the job was created, but its response was lost

The user wants one preview job.

  1. The app submits req-101 with coast/small.
  2. The service commits job-17 and its association with req-101.
  3. The response does not reach the app. The app cannot tell from that silence whether creation happened.
  4. The user chooses Check or retry this request. The app retains req-101 and the same inputs.
  5. While the identity record is retained, the service identifies job-17 as the original creation. It does not create another job.

The proposed visible result is “Your original job is job-17,” followed by the job's current availability or progress if that information can be obtained. The creation receipt is not a claim that rendering has finished.

A useful instruction to the agent is:

Preserve the identity of the unresolved request. Recover its original job when known. Do not turn an uncertain response into a new creation by generating a fresh request ID.

Disabling the button may help prevent accidental repeated clicks. It does not settle what happens when a request is retried after a lost response or by another client path.

Sequence 2: the user deliberately wants another job

The user has already requested one preview and now wants a second, separate job with identical settings.

  1. The original request req-101 created job-17.
  2. The user chooses Create another.
  3. The app assigns req-102 to that new intended creation.
  4. It submits the same coast/small inputs.
  5. The proposed result is another job, job-18, associated with req-102.

Identical inputs are allowed here because the user expressed a second operation. Reusing req-101 would instead ask to recover the first operation under this contract.

Give the agent both actions to design: Check or retry this request preserves an unresolved operation's ID; Create another begins a deliberate new operation. The example labels are suggestions, not a requirement to copy their wording into every interface.

Sequence 3: an old request arrives late

Now consider a replay that arrives after the original job has changed state.

  1. req-101 created job-17, and the service retained that association.
  2. A retry with the same ID and inputs was delayed in transit.
  3. In the meantime, the user removed job-17 from the fictional app.
  4. The delayed request arrives while the request-identity record is still retained.
  5. Under our proposed contract, it identifies the original operation. It does not create a replacement job.

The app should distinguish “this request originally created job-17” from “job-17 is available now.” If removal is known, report it. If current availability cannot be determined, preserve that uncertainty.

Deleting a job and forgetting its request identity are separate design decisions. The example requires the association to survive long enough for the supported recovery behavior; it does not prescribe an unlimited retention period.

After the identity record expires, this example makes no duplicate-prevention promise. A service that has forgotten the request cannot infer from an absent record alone whether it is seeing a fresh ID or an old replay. The recovery design needs an explicit validity and reconciliation policy. AWS likewise describes retention as service-dependent. Request lifetime and late arrivals

Put intent, identity and result in one matrix

All rows describe this fictional contract.

Situation Request ID and inputs Intended result What must stay explicit
First creation New req-101, coast/small Create job-17 and record the association A creation receipt is not completed rendering
Lost response, then matching retry Same req-101, same inputs Identify job-17; no additional job Silence did not prove the first attempt failed
Deliberate second creation New req-102, same inputs Create a separate job-18 Matching settings can still express new intent
Retained delayed replay after job removal Same req-101, same inputs Identify the original operation; no replacement job Original creation and current availability differ
Matching retry during pending creation Same req-101, same inputs Report pending or recover the eventual result; no second creation Concurrent first attempts need coordinated handling
Same ID, changed meaningful input req-101, now forest/small Reject the mismatch; preserve the original association Do not silently mutate the first request or issue a new ID
Recovery after identity may have expired Old ID, record unavailable Outcome unresolved until the recovery policy can reconcile it No deduplication guarantee beyond the defined lifetime

This table is a requirements artifact, not an implementation result. It gives a reviewer concrete cases to compare with the proposed design.

Decide what happens when the ID stays the same but intent changes

Suppose the app accidentally submits req-101 again with palette=forest.

For this example, choose a validation response such as Request ID already used with different settings. The response creates no additional job and leaves req-101 → job-17 unchanged. If the user wants a new forest job, they can deliberately begin another creation with a new ID.

Do not ask the agent to “fix” the mismatch by automatically replacing the ID. That would convert an ambiguous request into another side effect.

AWS describes a parameter-mismatch validation response for this situation. The fictional app still needs to define which inputs carry meaning and how their comparison works. A transport timestamp, for example, should not casually become a new business intent. Same request ID, different intent

Define the lifetime and the side effects you are protecting

Before implementation, ask for decisions about these boundaries:

Boundary Question the design must answer
Request scope Within which operation and authorized namespace is the ID meaningful?
Pending work What happens if two matching attempts arrive before either has a final result?
Commit How are the request association and the job record committed together?
Known failure Can the service establish that creation failed before any commit, rather than merely losing its response?
Retention How long is recovery supported, and what happens when the job itself is removed?
Expiry How can an old or expired request be recognized or reconciled? What remains unknown?
Later processing Does creating the record also schedule work, write files or notify another service?

The desired creation-only contract requires the identity record and job creation to share an atomic commit boundary. Recording a “done” flag after an unrelated creation step leaves a crash gap to investigate. Concurrent attempts need to be considered within the same design. The AWS article also makes the coordination of identity tracking and mutations part of its engineering discussion. Identity and mutation boundaries

Keep the promised effect narrow. One job record does not establish one worker execution, one generated file or one notification. Adding those effects would require their own failure and replay analysis.

An idempotency key is a piece of the contract. It is not proof that storage, concurrency, retention and downstream behavior meet that contract.

Give the coding agent a complete brief

The following brief carries the example's decisions and its unresolved questions together. It asks for a design before implementation where the contract is still incomplete.

Goal
Design request-identity behavior for a fictional app that creates preview-job
records from built-in, non-sensitive palette presets.

Example operation
create-preview-job in namespace board-a.
Meaningful inputs: palette and size.
The operation creates a job record only. Rendering, worker scheduling,
notifications and external services are outside this change.

Intent rules
- Retry the same logical creation with the same request ID and same inputs.
- A deliberate second creation uses a new ID, even with identical inputs.
- Same namespace/operation/ID with different meaningful inputs is a mismatch:
  reject it without creating another job or changing the original mapping.
- Never repair an uncertain result or mismatch by silently issuing a new ID.

Required cases
1. Creation commits but the response is lost. A retry identifies the original job.
2. The user chooses Create another. A new ID permits a second job.
3. A delayed replay arrives while the original request record is retained,
   including after that job was removed. It identifies the original operation;
   it does not recreate the removed job.
4. A concurrent matching retry arrives while creation is pending.
   It must not create a second job; define its pending response.
5. The same ID arrives with changed inputs. Reject the mismatch and preserve
   the original result.
6. Recovery happens after the retained identity may have expired.
   Keep the outcome unresolved; propose how to reconcile it. Do not claim
   a missing record alone proves the request is new.

Boundaries and open decisions
Show how recording request identity and creating the job share one atomic
commit boundary, including concurrent first attempts and crash points.
Separate an accepted creation receipt from the job's later completion.
Propose the namespace/authorization boundary, meaningful-input comparison,
retention interval, expiry recognition and recovery lookup before implementation.
No retention duration or expired-request behavior has been approved here.
Keep deduplication records and job deletion behavior explicitly related.

Deliverables
Return the state model, intent/ID/result matrix, three event sequences,
mismatch response and unresolved decisions first.
After those decisions are agreed, propose the smallest creation-only change
and checks for the agreed contract. Clearly separate planned checks from
executed results. Do not add automatic retries, workers, external calls
or a deployment as incidental work.

Review the explanation before accepting the change

Ask the agent to walk through the three sequences using the same IDs throughout. Then inspect the mismatch case, a concurrent matching attempt and the expiry case. A renamed field or disabled button is not enough to answer them.

Check that the delivered work distinguishes its design, implemented behavior and actual verification. A useful result tells you which evidence supports the creation contract and which assumptions remain open. If the implementation cannot support the intended recovery lifetime, narrow the contract or resolve that design question before describing retries as safe.