Common Errors

A list of common issues developers encounter when building and how to fix them.

Bug found? Email us, DM us on twitter or message full-time developer support on Discord.

Deployer (FW000s)

FW000: Create3Deployer.requireDeployerOnly()

Signatures were not sorted before being passed in - To fix this error, make sure to short sigs before passing them into requireDeployerOnly. You can do this by calling sigs.sort() before passing them in. It is also possible to run into this error if the hash that was signed was not the correct hash.

FW001: Create3Deployer.requireDeployerOnly()

Signature failed to be recovered. ercrecover returned the zero address. To fix this error, make sure to pass in enough valid signatures that sign the hash in the sigs array.

FW002: Create3Deployer.addDeployer()

Invalid Hash - To fix this error, ensure that hash is equal to hashAddDeployer().

FW003: Create3Deployer.removeDeployer()

Invalid Hash - To fix this error, ensure that hash is equal to hashRemoveDeployer().

FW004: Create3Deployer.setThreshold()

Threshold must be greater than 1 - To fix this error, ensure that threshold is greater than 1.

FW005: Create3Deployer.setThreshold()

Invalid Hash - To fix this error, make sure that hash is equal to keccak256(abi.encodePacked(_threshold)).

FW006: Create3Deployer.callChild()

Invalid Hash - To fix this error, make sure that hash is equal to keccak256(abi.encodePacked(child, data, _nonce, block.chainid)).

FW007: Create3Deployer.callChild()

Invalid Nonce, nonce must be 1 greater than the current nonce - To fix this error, ensure that _nonce is equal to the current nonce + 1.

FW008: Create3Deployer.callChild()

Call to child failed - To fix this error, check to see what is causing the call to the child to fail.

FW009: Create3Deployer.deploy()

Invalid Hash - To fix this error, ensure that hash is equal to keccak256(abi.encodePacked(_salt, _creationCode)).

FW010: FunWalletFactory.constructor()

Invalid Address, cannot be the zero address - To fix this error, ensure that _deployer is not equal to the zero address.

FW011: FunWalletFactory.constructor()

Invalid Address, cannot be the zero address - To fix this error, ensure that _funWalletImpAddress is not equal to the zero address.

FW012: FunWalletFactory.constructor()

Invalid Address, cannot be the zero address - To fix this error, ensure that _feeOracle is not equal to the zero address.

FW013: FunWalletFactory.constructor()

Invalid Address, cannot be the zero address - To fix this error, ensure that _walletInit is not equal to the zero address.

FW014: FunWalletFactory.constructor()

Unable to generate the address from this deployerSalt - To fix this error, make sure that FunWalletFactoryV1 has not already been deployed from the given create3deployer contract. If it has been, change FunWalletFactoryV1 to FunWalletFactoryV2 or another version.

FW015: FunWalletFactory.constructor()

Generated the wrong address from this deployerSalt - To fix this error, make sure that FunWalletFactoryV1 has not already been deployed from the given create3deployer contract. If it has been, consider changing FunWalletFactoryV1 to FunWalletFactoryV2 or another version.

FW016: FunWalletFactory.createAccount()

Call to initialize failed on the deployed proxy - To fix this error, make sure the initializerCallData is formatted correctly.

FW017: FunWalletFactory - Caller must be deployer

To fix this error, ensure that the function is called from the deployer address.

FW018: WalletInit.commit()

The previous commit has not expired - To fix this error, wait for the previous commit with this commitKey to expire. This should take at most 10 minutes.

FW019: WalletInit.validateSalt()

The hash at the commitKey does not match keccak256(abi.encode(seed, owner, initializerCallData)) - To fix this error, ensure the seed, owner, and initializerCallData are hashed and stored in commits at the corresponding commitKey.

FW020: WalletInit.validateSalt()

The new owner of the funwallet must match data.newFunWalletOwner from loginData - To fix this error, make sure the owner set in loginData matches the owner address returned from the tweet.

FW021: WalletInit.setOracle()

The address of the new _oracle must not be the zero address - To fix this error, ensure that _oracle is not the zero address.

FW022: Create3Deployer.deployFromChild()

Invalid Child Address - To fix this error, ensure the caller is a contract deployed from the Create3Deployer.

FW023: ImplementationRegistry.verifyIsValidContractAndImplementation()

Invalid Target Code Hash - To fix this error, ensure the caller is a contract targeted as an ERC1967ProxyData contract.

FW024: ImplementationRegistry.verifyIsValidContractAndImplementation()

Invalid Contract Implementation Address - To fix this error, make sure you have the minimum threshold amount of valid signatures.

FW025: ImplementationRegistry.addImplementation()

Invalid Signature Amount - To fix this error, make sure you have the minimum threshold amount of valid signatures.

FW026: ImplementationRegistry.removeImplementation()

Invalid Signature Amount - To fix this error, make sure you have the minimum threshold amount of valid signatures.

FW027: WalletInit.commit()

Unable to commit with a previously used commit hash - To fix this error, make sure you are not reusing someone else's commit hash. If there are conflicts, just regenerate the seed randomly.

FW028: MultiSigDeployer.constructor()

Threshold can't be greater than deployers length - To fix this error, make sure the threshold value is not 0.

FW029: WalletInit.invalidateUsedSeed()

msg.sender must equal funwalletfactory - To fix this error, ensure you are calling this function from the FunWalletFactory contract.

FW030: WalletInit.setFunWalletFactory()

funwalletfactory address cannot be set to 0 - To fix this error, make sure you are passing in the valid funwalletfactory address.

FW031: WalletInit.validateSalt()

Seed has already been used - To fix this error, make sure you are not using an existing salt.

FW032: FunWalletFactory.setFeeOracle()

Cannot set the fee oracle address to 0 - To fix this error, make sure you are using the correct address for the fee oracle.

FW033: FunWalletFactory.constructor()

Invalid Address, cannot be the zero address - To fix this error, make sure _entryPoint is not equal to the zero address.

FW034: Create3Deployer.callChild()

Value not equal to msg.value - To fix this error, make sure msg.value is equal to the value parameter.

Modules (FW100s)

FW100: Module.execute()

execute() needs to be overridden - To fix this error, ensure you are overriding the execute method in your module.

FW101: ApproveAndExec.approveAndExecute()

The approveData's first four bytes must be the approve() function selector - To fix this error, change approveData so that the first four bytes are bytes4(keccak256('approve(address,uint256)')).

FW102: ApproveAndSwap.constructor()

_wethAddr cannot be the zero address - To fix this error, make sure _wethAddr is not set to the zero address.

FW103: ApproveAndSwap.constructor()

_router cannot be the zero address - To fix this error, ensure _router is not set to the zero address.

FW104: ApproveAndSwap.executeSwapEth()

msg.sender does not have enough WETH - To fix this error, make sure msg.sender has a WETH balance greater than or equal to amount.

FW105: ApproveAndSwap.internalSwap()

Approve failed - To fix this error, ensure you have correctly formatted the approve function.

FW106: AaveWithdraw.execute()

Withdrawing a zero balance - You are trying to withdraw from Aave, but you don't have a balance.

FW107: ApproveAndExec.approveAndExecute()

Approve failed - The token you tried to approve has failed.

FW108: UniswapV3LimitOrder.execute()

Approval Failed - You are trying to withdraw from Aave, but you don't have a balance.

FW109: UniswapV3LimitOrder.constructor()

Router cannot be the zero address - Make sure you are not passing the zero address when initializing the module.

FW110: UniswapV3LimitOrder.constructor()

Quoter cannot be the zero address - Make sure you are not passing the zero address when initializing the module.

Oracles (FW200s)

FW200: FeePercentOracle.setValues()

feepercent must be less than or equal to 100% - To fix this error, ensure _feepercent is less than or equal to 10 ** _decimals.

FW201: FeePercentOracle.withdrawEth()

ETH transfer failed - To fix this error, investigate why the ETH withdrawal failed. It is likely because amount was greater than the ETH balance in the FeePercentOracle.

FW202: TokenPriceOracle.getTokenValueOfEth()

Chainlink aggregator price must be greater than 0 - To fix this error, retry the call and ensure the price is greater than 0.

FW203: TokenPriceOracle.getTokenValueOfEth()

Chainlink aggregator updatedAt must be greater than 0 - To fix this error, retry the call and ensure updatedAt is greater than 0.

FW204: TokenPriceOracle.getTokenValueOfEth()

Chainlink aggregator answeredInRound must be greater than or equal to roundId - To fix this error, retry the call and ensure answeredInRound is greater than or equal to roundId.

FW205: TwitterOracle.batchSetTweet()

socialHandles, loginTypes, seeds, and owners lengths must match - To fix this error, ensure all arrays passed into this function are the same length.

FW206: TwitterOracle.setTweet()

The seed from Twitter cannot be empty - To fix this error, make sure the seed you post on Twitter is not empty {}.

FW207: TwitterOracle.setTweet()

The address from Twitter cannot be 0 - To fix this error, ensure the address you post on Twitter for the new owner is not the zero address. Otherwise, you would be unable to claim ownership of the FunWallet.

FW208: TwitterOracle.batchSetTweet()

The seed from Twitter cannot be empty - To fix this error, make sure the seed you post on Twitter is not empty {}.

FW209: TwitterOracle.batchSetTweet()

The address from Twitter cannot be 0 - To fix this error, ensure the address you post on Twitter for the new owner is not the zero address. Otherwise, you would be unable to claim ownership of the FunWallet.

FW210: TwitterOracle.fetchTweet()

The seed from Twitter cannot be empty - To fix this error, make sure the seed you post on Twitter is not empty {}.

FW211: TwitterOracle.fetchTweet()

The address from Twitter cannot be 0 - To fix this error, ensure the address you post on Twitter for the new owner is not the zero address. Otherwise, you would be unable to claim ownership of the FunWallet.

Paymaster (FW300s)

FW300: BasePaymaster.constructor()

Entrypoint address cannot be the zero address - To fix this error, ensure the entrypoint address is not the zero address.

FW301: BasePaymaster._requireFromEntryPoint()

msg.sender must be from the entrypoint - To fix this error, make sure msg.sender is from the entrypoint.

FW302: GaslessPaymaster.batchActions()

The ith delegate call failed - To fix this error, ensure the calldata for data[i] is a valid call.

FW303: GaslessPaymaster.batchActions()

batchActions consumed more ETH than allocated by msg.value - To fix this error, increase the amount of msg.value passed to this function.

FW304: GaslessPaymaster._withdrawDepositTo()

The withdrawal has not been unlocked - To fix this error, wait until block.number is greater than the unlockBlock for the sender and ensure unlockBlock[sender] is nonzero.

FW305: GaslessPaymaster._withdrawDepositTo()

The balances of the sender must be greater than the withdrawal amount - To fix this error, decrease the amount you are trying to withdraw.

FW306: GaslessPaymaster._validatePaymasterUserOp()

The userOp.paymasterAndData must have a length of 40 - To fix this error, change the paymasterAndData field in the userOp to have a length of 40.

FW307: GaslessPaymaster._validatePaymasterUserOp()

The verificationGasLimit must be greater than COST_OF_POST in GaslessPaymaster - To fix this error, increase the verificationGasLimit in the userOp.

FW308: GaslessPaymaster._validatePaymasterUserOp()

The sponsor's ETH is not locked for use - To fix this error, ensure the sponsor's ETH is locked using lockDeposit().

FW309: GaslessPaymaster._validatePaymasterUserOp()

The sponsor needs to approve the spender - To fix this error, ensure you approve the spender using setSpenderWhitelistMode() or setSpenderBlacklistMode(), and the sponsor's list mode is set to whitelist mode or blacklist mode using setListMode().

FW310: GaslessPaymaster._validatePaymasterUserOp()

The sponsor does not have sufficient ETH in the paymaster to cover this operation - To fix this error, make sure you stake enough ETH from the sponsor's address using addDepositTo().

FW311: GaslessPaymaster.addDepositTo()

msg.value must be greater than or equal to the amount - To fix this error, ensure that msg.value is greater than or equal to amount.

FW312: TokenPaymaster.batchActions()

The ith delegate call failed - To fix this error, ensure the calldata for data[i] is a valid call.

FW313: TokenPaymaster.batchActions()

batchActions consumed more ETH than allocated by msg.value - To fix this error, increase the amount of msg.value passed to this function.

FW314: TokenPaymaster._addTokenDepositTo()

Token decimals must be greater than 0 - To fix this error, change the decimals in the token using setTokenData().

FW315: TokenPaymaster._withdrawTokenDepositTo()

The token is not unlocked for withdrawal - To fix this error, call unlockTokenDepositAfter().

FW316: TokenPaymaster._withdrawTokenDepositTo()

You are withdrawing more tokens than you have in balance - To fix this error, call getTokenBalance() to check your token balance and ensure amount is less than that.

FW317: TokenPaymaster._withdrawEthDepositTo()

The token is not unlocked for withdrawal - To fix this error, call unlockTokenDepositAfter() with ETH as the token.

FW318: TokenPaymaster._withdrawEthDepositTo()

You are withdrawing more Ether than you have in balance - To fix this error, call getTokenBalance() with ETH as the token to check your balance and ensure amount is less than that.

FW319: TokenPaymaster._getTokenValueOfEth()

The call to the token oracle failed - To fix this error, check the token oracle and call setTokenData() to change the oracle if it is broken.

FW320: TokenPaymaster._reimbursePaymaster()

Failed to reimburse the paymaster with tokens via permitTransfer() - To fix this error, make sure you have permitted the paymaster to spend your tokens.

FW321: TokenPaymaster._reimbursePaymaster()

Spender doesn't have enough tokens - To fix this error, ensure you have enough tokens in the token paymaster via addTokenDepositTo().

FW322: TokenPaymaster._validatePaymasterUserOp()

The paymasterAndData length must be 60 - To fix this error, make sure to set the paymasterAndData length to 60.

FW323: TokenPaymaster._validatePaymasterUserOp()

The verificationGasLimit must be greater than COST_OF_POST - To fix this error, ensure you set the userOp's verificationGasLimit to be greater than COST_OF_POST.

FW324: TokenPaymaster._validatePaymasterUserOp()

The sponsor must lock their ETH - To fix this error, ensure the sponsor has locked their ETH by calling lockTokenDeposit() from the sponsor address.

FW325: TokenPaymaster._validatePaymasterUserOp()

The account must lock their tokens - To fix this error, ensure the user of the token paymaster has locked their tokens by calling lockTokenDeposit() from their address.

FW326: TokenPaymaster._validatePaymasterUserOp()

The sponsor ETH balance must be greater than maxCost - To fix this error, ensure the sponsor's ETH balance is greater than maxCost.

FW327: TokenPaymaster._validatePaymasterUserOp()

The sponsor must approve the spender - To fix this error, make sure the sponsor has approved the spender by calling setSpenderWhitelistMode() or setSpenderBlacklistMode(), and the sponsor's list mode is set to whitelist mode or blacklist mode using setListMode().

FW328: TokenPaymaster._validatePaymasterUserOp()

The sponsor must have approved the token to the paymaster - To fix this error, make sure the sponsor has approved the token to the paymaster by calling setTokenWhitelistMode() or setTokenBlacklistMode(), and the sponsor's list mode is set to whitelist mode or blacklist mode using setTokenListMode().

FW329: TokenPaymaster._validatePaymasterUserOp()

The permitted token must be equal to the token you are trying to pay with if using permit - To fix this error, ensure the permitted token is equal to the token you are trying to pay with if using permit.

FW330: TokenPaymaster._validatePaymasterUserOp()

The permitted transfer recipient must be the token paymaster - To fix this error, ensure you permit the token paymaster to spend your tokens.

FW331: TokenPaymaster._validatePaymasterUserOp()

The permitted transfer amount must be greater than or equal to maxTokenCost - To fix this error, ensure the permitted transfer amount is greater than or equal to maxTokenCost.

FW332: TokenPaymaster._validatePaymasterUserOp()

If permit was not used, make sure the token paymaster was approved to spend tokens by the sponsor or enough tokens were deposited into the TokenPaymaster - To fix this error, ensure the token paymaster was approved (approve()) to spend tokens by the sponsor or enough tokens were deposited into the TokenPaymaster via addTokenDepositTo().

FW333: TokenPaymaster.addEthDepositTo()

Ensure msg.value is greater than or equal to amount - To fix this error, ensure that msg.value is greater than or equal to amount.

FW334: TokenPaymaster.addTokenDepositTo()

Sponsor cannot be the zero address - To fix this error, ensure the sponsor is not the zero address.

FW335: TokenPaymaster.addTokenDepositTo()

Target cannot be the zero address - To fix this error, ensure the target is not the zero address.

FW336: TokenPaymaster.addTokenDepositTo()

Token address cannot be the zero address - To fix this error, ensure the token address is not the zero address.

FW337: TokenPaymaster.addTokenDepositTo()

Spender address cannot be the zero address - To fix this error, ensure the spender address is not the zero address.

FW338: TokenPaymaster.addTokenDepositTo()

The token oracle cannot be the zero address - To fix this error, ensure the token oracle is not the zero address.

FW339: TokenPaymaster.addTokenDepositTo()

The tokenAddress cannot be the zero address - To fix this error, ensure the tokenAddress is not the zero address.

FW340: TokenPaymaster.addTokenDepositTo()

The token decimals must be greater than 0 - To fix this error, ensure the token decimals are greater than 0.

FW341: TokenPaymaster.addTokenDepositTo()

The Chainlink aggregator cannot be the zero address - To fix this error, ensure the Chainlink aggregator is not the zero address.

FW342: TokenPaymaster.removeTokenData()

The token doesn't exist in tokens - To fix this error, ensure the token address is not the zero address.

FW343: TokenPaymaster.removeTokenData()

The tokenListIndex doesn't match with the tokenAddress - To fix this error, ensure the token at tokenList[tokenListIndex] matches the tokenAddress.

FW344: GaslessPaymaster.batchActions()

Cannot recursively call batchActions from within batchActions - To fix this error, ensure you are not recursively calling batchActions from within batchActions.

FW345: TokenPaymaster.batchActions()

Cannot recursively call batchActions from within batchActions - To fix this error, ensure you are not recursively calling batchActions from within batchActions.

FW346: TokenPaymaster.postOp()

Invalid Permit transfer amount - To fix this error, ensure your permit transfer transfers the correct amount of tokens.

FW347: TokenPaymaster._reimbursePaymaster()

Invalid amount of tokens transferred - The likely cause of this error is using a deflationary token that charges a tax when you transfer tokens. To fix this error, make sure you are transferring the correct amount of tokens and accounting for the tax/deflation.

FW348: UserAuthentication.init()

The groupId count must be equal to the groups length - To fix this error, ensure the number of groupIds equals the number of groups.

FW349: TokenPaymaster.calculatePostOpGas()

Invalid Auth Type - To fix this error, ensure the auth type is correct.

FW350: TokenPaymaster._validatePaymasterUserOp()

Does not have enough balance of tokens - To fix this error, ensure you have enough tokens to permit transfer.

FW351: BasePaymaster.\withdrawStakeFromEntryPoint()

Cannot withdraw to address zero - To fix this error, ensure you are not withdrawing to address zero.

Validations (FW400s)

FW401: RoleBasedAccessControl: addTargetWildcard(), removeTargetWildcard(), addRuleToRole(), removeRuleFromRole(), addUserToRole(), removeUserFromRole()

FW402: RoleBasedAccessControl.isValidAction(), isValidActionAndFee() - Invalid Target

To fix this error, ensure that the target you are calling is included in the merkle root of allowed targets verified by the rule. If this doesn't work, verify that you are using the correct merkle root implementation.

FW403: RoleBasedAccessControl: isValidAction(), isValidActionAndFee() - Invalid Selector

To fix this error, confirm that the selector you are calling is part of the merkle root of allowed selectors verified by the rule. If this doesn't work, verify that you are using the correct merkle root implementation.

FW404: RoleBasedAccessControl: addOwner(), removeOwner() - Invalid Owner

To fix this error, ensure that the ownerId is neither 0 nor an existing owner.

FW405: RoleBasedAccessControl: setRule(), deleteRule() - Invalid Rule Id

To fix this error, make sure the ruleId is not 0.

FW406: RoleBasedAccessControl: isValidAction(), isValidActionAndFee() - Rule deadline passed

To fix this error, ensure that the rule you are using has a deadline that has already passed.

FW408: RoleBasedAccessControl: addTargetWildcard(), removeTargetWildcard(), addRuleToRole(), removeRuleFromRole(), addUserToRole(), removeUserFromRole()

FW410: RoleBasedAccessControl: isValidAction(), isValidActionAndFee() - Rule not added to role

To fix this error, make sure the rule has been added to the role.

FW411: RoleBasedAccessControl: isValidAction(), isValidActionAndFee() - Invalid Value is above limit

To fix this error, make sure the value for the execution call is less than the specified limit.

FW412: RoleBasedAccessControl: isValidAction(), isValidActionAndFee() - Invalid Fee value is above limit

To fix this error, ensure that the fee value for the execution call is less than the specified limit.

FW413: RoleBasedAccessControl: isValidActionAndFee() - Invalid Fee Recipient is not whitelisted

To fix this error, make sure the fee recipient is included in the rule fee merkle root.

FW414: RoleBasedAccessControl: isValidActionAndFee() - Fee Token is not whitelisted

To fix this error, ensure the fee token is included in the rule fee merkle root.

FW417: RoleBasedAccessControl: isValidActionAndFee() - Rule Does not exist

To fix this error, ensure the rule you are trying to use actually exists.

FW418: RoleBasedAccessControl: isValidActionAndFee() - User not in role

To fix this error, make sure the user is a member of the specified role.

FW419: RoleBasedAccessControl: setRule() - Invalid feeRecipientTokenMerkleRootHash

To fix this error, ensure the feeRecipientTokenMerkleRootHash is not zero.

FW420: RoleBasedAccessControl: setRule() - Invalid targetSelectorMerkleRootHash

To fix this error, make sure the targetSelectorMerkleRootHash is not zero.

FW421: RoleBasedAccessControl: addOwner(), removeOwner(), setRule(), deleteRule(), addTargetWildcard(), removeTargetWildcard(), addRuleToRole(), removeRuleFromRole(), addUserToRole(), removeUserFromRole()

FW422: RoleBasedAccessControl: init() - Wallet has not been initialized

To fix this error, ensure that the wallet has been initialized with the validation contract.

FunWallet (FW500s)

FW500: FunWallet.initialize()

The entrypoint cannot be the zero address - To fix this error, ensure the entrypoint is not the zero address.

FW501: FunWallet.initialize()

The msg.sender cannot be the address of the Funwallet contract - To fix this error, make sure the msg.sender is not the address of the Funwallet contract.

FW502: FunWallet._requireFromFunWalletProxy()

The function must be called from the Funwallet proxy - To fix this error, ensure msg.sender == funwallet.

FW503: FunWallet.updateEntryPoint()

The new entrypoint address cannot be the zero address - To fix this error, make sure the new entrypoint address is not the zero address.

FW504: FunWallet.depositToEntryPoint()

Not enough ETH in the Funwallet - To fix this error, ensure the Funwallet has more than the amount of ETH you are trying to deposit.

FW505: FunWallet._transferEthFromEntryPoint()

Withdrawing ETH from the entrypoint failed - To fix this error, retry the operation and make sure you have a balance greater than the amount in the entrypoint.

FW506: FunWallet._requireFromModule()

Make sure a FunwalletFactory deployed the module - To fix this error, make sure msg.sender is the module.

FW507: FunWallet._requireFromEntryPoint()

The msg.sender must be the entrypoint - To fix this error, make sure msg.sender is the entrypoint.

FW508: WalletFee._transferEth()

The ETH transfer failed - To fix this error, retry the operation and make sure you have a balance greater than the amount in the wallet.

FW509: WalletFee._handleFee()

The developer ETH transfer failed - To fix this error, retry the operation and ensure you have a balance greater than the amount in the wallet.

FW510: WalletFee._handleFee()

The FunOracle ETH transfer failed - To fix this error, retry the operation and ensure you have a balance greater than the amount in the wallet.

FW511: WalletValidation.initValidations()

The WalletValidations contract has already been initialized - Don't call initValidations() more than once.

FW512: WalletValidation.initValidations()

Make sure there are more than zero validations - To fix this error, ensure there are more than zero validations, and the number of validation contract addresses is equal to the number of initCallData elements.

FW513: WalletValidation.initValidations()

Make sure there are no duplicate validation contract addresses - To fix this error, ensure there are no duplicate validation contract addresses in validationData.

FW514: WalletValidation._validateUserOp()

Make sure the signature length is greater than 0 - To fix this error, ensure the signature length is greater than 0.

FW515: WalletValidation.isValidSignature()

Make sure the number of validations is greater than zero - To fix this error, ensure the number of validations is greater than zero.

FW516: WalletValidation._requireValidValidation()

The validation failed - To fix this error, ensure the validation contract returns true.

FW517: WalletValidation._requireValidValidationFormat()

The validation was incorrectly formatted - To fix this error, ensure the validation contract address is not the zero address, the validation is valid, and the address is not the zero address.

FW518: WalletValidation._requireValidPrevValidation()

The previous validation must be linked to this validation - To fix this error, ensure the previous validation is linked to this validation when adding or removing the validation.

FW519: WalletValidation.getValidations()

You must have more than zero validations to get validations - To fix this error, ensure there is a nonzero amount of validations.

FW520: WalletValidation.addValidation()

The caller must be this wallet - To fix this error, ensure you are calling addValidation() from your Funwallet.

FW521: WalletValidation.removeValidation()

The caller must be this wallet - To fix this error, ensure you are calling removeValidation() from your Funwallet.

FW522: WalletValidation.updateValidation()

The caller must be this wallet - To fix this error, ensure you are calling updateValidation() from your Funwallet.

FW523: WalletModules.permitTransfer()

Invalid Permit Signature - To fix this error, make sure you have a valid permit signature.

FW524: FunWallet.executeBatch()

All batch inputs must have the same length - To fix this error, ensure all batch inputs have the same length.

FW524: WalletValidation.getValidations()

No Validations in the wallet - To fix this error, ensure the wallet has validation contracts.

Utils (FW600s)

FW600: DataLib: getCallData()

Make sure you are calling either execFromEntryPoint() or execFromEntryPointWithFee() from your Funwallet.

FW601: Ownable2StepNoRenounce: renounceOwnerShip()

Don't call this function.