## TL;DR

Make retries fire only on retryable statuses (429 and 5xx), never on 400. A 400 means the request is malformed; replaying the identical bad request five times looks like abuse. Fix the malformed request, then gate retries by status code.

```
generated client's retry logic retried 400s  -  a malformed request was replayed 5 times and triggered the provider's fraud flags
```

## Steps

1. Pull one failed request and read the 400 response body. Providers usually name the offending field. Expected: you know exactly what was malformed.

2. Fix the request construction so the malformed field is correct or omitted. Expected: a single manual request now returns 2xx or a different, legitimate error.

3. Change the retry policy: retry only on 429 and 5xx (and network errors); treat 400, 401, 403, 404, 422 as final. Expected: the retry config lists explicit retryable statuses instead of "retry on any error".

4. Add idempotency keys to mutating requests so that even a legitimate retry can never double-apply. Expected: replays are safe by construction.

5. Check the provider dashboard or contact support to clear the fraud flag if the account is still restricted. Expected: the flag is lifted and stays lifted.

6. Add an alert on repeated identical 400s so a malformed request gets fixed on the first occurrence instead of the fiftieth. Expected: the next malformed request pages someone after a small threshold, not after a ban.

## Use this when

- Logs show the same request failing with 400 multiple times in a row.
- An account got flagged or throttled after a burst of identical bad requests.
- A generated retry wrapper retries on "any error" without status gating.

## Not for this skill when

- Retries are hitting 429 or 5xx - that is legitimate retry behavior, tune backoff instead.
- The 400 comes from the provider side changing validation - then the request was fine yesterday; update it to the new rules.
- The problem is duplicate side effects from successful retries - that is idempotency, not retry gating.

## Variant phrasings

- retry logic replayed 400 bad requests and triggered fraud detection
- generated client retries malformed requests until account flagged
- provider fraud flags from repeated identical 400s

## Why it happens

Generated retry wrappers usually catch broadly: "if the request failed, try again." A 400 fails, so it retries, and the request is deterministic, so the same malformed body goes out five times. Fraud systems are tuned to flag exactly that shape: identical failing requests at machine speed.

## Edge cases

- 400s caused by transient provider-side validation deploys are rare; still treat 400 as final and alert a human.
- Some providers return 400 for rate limiting (undocumented); if you see this, gate on the response body, not just the status.
- Retry budgets: cap total attempts even for retryable statuses so a poison request cannot loop forever.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_bx7UQUjz8p2vA562NkAItA
