Skip to content

This tutorial explains how to debug common issues you may face when sending UserOperations.

Execution reverted

The UserOperation was able to make it onchain, but an error occurred in one of the smart contracts it interacted with, and thus the entire operation had to be reverted. This can be due to

  • Not enough gas to pay for execution
    • Try increasing the preVerificationGas or callGasLimit padding
  • An issue with the callData of your UserOperations
    • This is an issue with your dapp's smart contract, which you will need to debug.

You can use a tool like Tenderly to help simulate and debug the UserOperation.

Issue regarding gas estimation

If you think the issue may be related to gas, simulate using the Entrypoint contract, 0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789, and pasting in your UserOperation into the tuple field.

For example, your UserOperation may look something like

{
  "callData": "0xb61d27f600000000000000000000000066519fcaee1ed65bc9e0acc25ccd900668d3ed490000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000443f84ac0e0000000000000000000000001e3143e0ed8c0ea51f1551b6c355e02f3e0baae0000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000",
  "paymasterAndData": "0xc484bcd10ab8ad132843872deb1a0adc1473189c000066cd03db0000000000000098973f00000a968163f0a57b400000018633de6cf5e53752c5eac49e8f8ffb4ecd16b2afe7b4074086d6693536a9ab1f117bae0b427f83f94246c34d25add97b05e8a73859c2dceef6ee730ab2842bf31b",
  "sender": "0x1e3143E0ED8C0Ea51F1551B6c355e02f3e0bAae0",
  "initCode": "0x",
  "maxFeePerGas": "3000000000",
  "maxPriorityFeePerGas": "1000000000",
  "nonce": "31815307923431762811356398485504",
  "signature": "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000041ca7a742cff01aa9d5e377c5a146b5d8f03a4e44bd1817b1899bf7e0ff6885ed63294c69f017fe47f385c046055cc687e503bba08513ff52fbf21dcd8019c1f1d1b00000000000000000000000000000000000000000000000000000000000000",
  "callGasLimit": "257565",
  "preVerificationGas": "96024",
  "verificationGasLimit": "87888"
}

You can use the simulateHandleOp function and pass that UserOperation in the op field (don't forget to add array brackets around it, because technically it handles a "bundle" of UserOperations).

Expand for images and click to enlarge
Tenderly - Entrypoint
Tenderly Entrypoint

Execution reverted with data

Error may look something like this

cause: {
  "code": -32004,
  "message": " - execution reverted with data",
  "data": "0xed6c3dec00000000000000000000000036e53f56454e1206f775dafe2b33c1b737c43632"
}

You can use a tool like https://bia.is/tools/abi-decoder/ to upload your ABI, enter the data in, and decode the error message. Try using the ABI of every smart contract your dapp could be interacting with.

Execution reverted for an unknown reason

Similar to above, except your contract is reverting without any error codes. Try reviewing your smart contract's code, your callData, and using Tenderly to debug. It may help to have your contract verified.

The example below shows you how to debug your own smart contract.

  • Insert any address - Enter your smart contract's address here
  • Enter raw input data - Enter the callData of your contract's function (right after callData = encodeFunctionData())
Expand for images and click to enlarge
Tenderly - Contract Debug
Tenderly Debug

Invalid chain id

You might be using the mainnet RPC url instead of the testnet RPC url (or vis versa). Make sure you select the right network in the CDP portal

Expand for images and click to enlarge
Paymaster chain
Paymaster Chain ID

Invalid UserOperation signature or paymaster signature

UserOperation rejected because account signature check failed (or paymaster signature, if the paymaster uses its data as signature).

This likely means that you updated the UserOperation after getting a signature from our Paymaster service. Our Paymster signs the UserOperation with the UserOperation itself, so make sure you're not making any changes to the UserOperation after it's already been signed by our Paymaster paymasterClient.getPaymasterData(). If you need to adjust things like callData, preVerificationGas, or callGasLimit, you will need to receive a new signature from our Paymaster. Also if you're handling multiple UserOperation, make sure the paymaster signature matches the right UserOperation.