# Transaction is being retried by relayer despite throwing DefenderApiResponseError 400 error

**URL:** <https://forum.openzeppelin.com/t/transaction-is-being-retried-by-relayer-despite-throwing-defenderapiresponseerror-400-error/38008>\
**Category:** Defender\
**Created:** [October 5, 2023, 7:47am UTC](https://forum.openzeppelin.com/t/transaction-is-being-retried-by-relayer-despite-throwing-defenderapiresponseerror-400-error/38008 "2023-10-05T07:47:44Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jon\_Achai](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/jon_achai/32/19458_2.png) [@Jon\_Achai](https://forum.openzeppelin.com/u/Jon_Achai)\
**Post date:** [October 5, 2023, 7:47am UTC](https://forum.openzeppelin.com/t/transaction-is-being-retried-by-relayer-despite-throwing-defenderapiresponseerror-400-error/38008/1 "2023-10-05T07:47:44Z")

</div>

I'm using the Defender relayer to perform a transaction on a polygon contract.  
It works smoothly 99% of the time however we're experiencing some very odd behavior when it does fail.

We got relayer funds low alert at the time but it could have been also the 120 tx/hour limit.  
The relayer was topped up, and at no point there was not enough MATIC to perform the transaction.

However, our app did receive the following errors  
Request failed with status code 400 DefenderApiResponseError: Request failed with status code 400

```auto
at rejectWithDefenderApiError (/workspace/node_modules/defender-base-client/lib/api/api.js:11:27)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async /workspace/node_modules/defender-relay-client/lib/api/index.js:92:21
    at async ApiRelayer.apiCall (/workspace/node_modules/defender-base-client/lib/api/client.js:26:20)
    at async DefenderRelaySigner.sendTransaction (/workspace/node_modules/defender-relay-client/lib/ethers/signer.js:122:15)

```

This was caught by our app, communicated to the user, and was attempted later and succeeded.  
However, to our surprise it looks like this was a false negative, because all of those transactions did go through which is very very bad (imagine sending double tokens!)

Is this a bug on your end?  
Is this expected behavior? How can prevent this from happening and trust that an error means failed, and if it's not failed how can I get the tx hash of this transaction.

Thanks,  
Jonathan

**💻 Environment**  
OpenZeppelin Defender relayer on Polygon using ethers.js and DefenderRelayProvider

**📝Details**  
For example, the below transaction was sent when my app received an error back

> **[Polygon Transaction Hash (Txhash) Details | PolygonScan](https://polygonscan.com/tx/0xf5af6f340367b4e83f1fcd98c866d023ed0d0c3cdf9cad25849392178ec4ff51)**
>
> Polygon (MATIC) detailed transaction info for txhash 0xf5af6f340367b4e83f1fcd98c866d023ed0d0c3cdf9cad25849392178ec4ff51. The transaction status, block confirmation, gas fee, MATIC, and token transfer are shown.

Later the action was attempted again by the client (slighly different tokens selected, but some were the same and the ended up with double spend)

> **[Polygon Transaction Hash (Txhash) Details | PolygonScan](https://polygonscan.com/tx/0x81e63dfbe0f79b746d7e88d6232f13ef80977a12d5e89ed50ab36f214b9413a7)**
>
> Polygon (MATIC) detailed transaction info for txhash 0x81e63dfbe0f79b746d7e88d6232f13ef80977a12d5e89ed50ab36f214b9413a7. The transaction status, block confirmation, gas fee, MATIC, and token transfer are shown.

For the 0xf5af6f340367b4e83f1fcd98c866d023ed0d0c3cdf9cad25849392178ec4ff51 transaction I received the error above and assumed it failed (didn't get the tx hash back but an exception)

**🔢 Code to reproduce**

```auto
const assetsContract = await getAssetsContract();
    const minterWallet = await getMinterWallet();

    const contractWithSigner = assetsContract.connect(minterWallet);

    const transaction = await contractWithSigner.mintToMultipleWallets(
      walletAddresses,
      tokenIds,
      tokenAmounts
    );

    return transaction.hash;

```

Where assetsContract is :

```auto
const credentials = {
      apiKey: RELAYER_API_KEY,
      apiSecret: RELAYER_SECRET_KEY,
    };

    const provider = new DefenderRelayProvider(credentials);

    const assets = new Contract(
      contractAddress,
      contractAbi,
      provider
    );

    return assets;

```

Minter wallet is:

```auto
const credentials = {
      apiKey: RELAYER_API_KEY,
      apiSecret: RELAYER_SECRET_KEY,
    };

    const provider = new DefenderRelayProvider(credentials);
    const signer = new DefenderRelaySigner(credentials, provider, {
      speed: config.web3_transaction_speed,
    });

    return signer;

```

---

<div class="post-metadata">

**Author:** ![emnul](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/emnul/32/18922_2.png) [@emnul](https://forum.openzeppelin.com/u/emnul)\
**Post date:** [October 6, 2023, 10:12pm UTC](https://forum.openzeppelin.com/t/transaction-is-being-retried-by-relayer-despite-throwing-defenderapiresponseerror-400-error/38008/2 "2023-10-06T22:12:41Z")

</div>

Hi @Jon_Achai ,

Your error indicates that the request sent to the server was malformed or invalid, and the server could not understand it. The error could be due to a wrong URL, a missing or incorrect parameter, or an authorization issue. To fix this error, you would need to check the request and response objects to identify what went wrong, and correct the issue. This is not a Defender error, but a client error.

It's hard to say what the core issue is without having a full view into the application, but this sounds like an error handling issue on the application side of things.
