{"id":"ERC-6093","name":"Custom Errors for Common Tokens","status":"Final","chain":"both","category":{"id":"comprehension","name":"Comprehension & Display","description":"Making blockchain data readable to humans"},"journeyStages":[{"id":"reading","name":"Reading & Understanding","description":"Interpreting what you're being asked to do"}],"uxImpact":"Token errors become specific and actionable — 'Insufficient balance: have 50, need 100' instead of generic 'transfer failed'. Design implications: parse custom errors to show precise failure reasons, display relevant values (balances, allowances) in error messages, suggest fixes inline (e.g., 'Approve more tokens'). Design decisions: which error details to expose to users vs log internally, how to present technical info accessibly, fallback handling for non-standard errors, translating error codes to user-friendly language. Addresses the Blanket Warnings pain point (Medium severity, Unsolved) — identical warnings for routine and catastrophic actions train users to ignore all alerts. ERC-6093 enables contextual, specific error messages.","hasDetailedContent":true,"content":{"id":"ERC-6093","summary":"ERC-6093 standardizes error messages for tokens. Instead of \"execution reverted\", you get \"ERC20InsufficientBalance: have 5 USDC, need 10 USDC\". Human-readable errors that explain exactly what went wrong and often how to fix it. This transforms cryptic failures into actionable feedback.","applicability":{"whenToUse":["Your product addresses: error messages are unhelpful hex or generic text.","Your users don't know how to fix failed transactions.","The flow should deliver: \"ERC20InsufficientBalance(sender, balance, needed)\".","You are designing a actionable error message experience with visible states and recovery paths."],"whenToAvoid":["Decode and display human message.","Parse error, show specific reason.","Offer actions: \"Approve more\" or \"Get tokens\".","Users never see addresses, amounts, or signing payloads in your UI."]},"designerTakeaways":["You can design UI that delivers \"ERC20InsufficientBalance(sender, balance, needed)\".","You can design UI that delivers \"Need 10 more USDC. Current balance: 5 USDC\".","You can standard error signatures work everywhere."],"problemsSolved":[{"problem":"Error messages are unhelpful hex or generic text","oldWay":"\"execution reverted\" or \"0x4e487b71...\"","newWay":"\"ERC20InsufficientBalance(sender, balance, needed)\"","impact":"critical"},{"problem":"Users don't know how to fix failed transactions","oldWay":"\"Transaction failed. Try again?\" (why?)","newWay":"\"Need 10 more USDC. Current balance: 5 USDC\"","impact":"critical"},{"problem":"Each token had different error formats","oldWay":"Parse custom errors for each protocol","newWay":"Standard error signatures work everywhere","impact":"high"}],"uxPatterns":[{"name":"Actionable Error Message","description":"Clear error with solution","mockup":"concept/verify-safety","userFlow":["Transaction reverts with custom error","App decodes error using ERC-6093 ABI","Extracts balance, needed amount","Shows clear comparison","Offers ways to resolve"]},{"name":"Approval Error","description":"Handle insufficient allowance clearly","mockup":"generic/token-approval","userFlow":["Swap fails with allowance error","Decode ERC20InsufficientAllowance","Show current vs needed","One-click approve more","Retry original action"]}],"uiComponents":[{"name":"ErrorDecoder","description":"Parses ERC-6093 errors into readable format","states":["parsing","decoded","unknown"],"props":["errorData","onDecode"]},{"name":"BalanceErrorCard","description":"Shows balance shortfall with context","states":["insufficient-balance","insufficient-allowance"],"props":["have","need","token","actionSuggestions"]},{"name":"ErrorRecoveryActions","description":"Buttons to resolve the error","states":["ready","resolving","resolved"],"props":["actions[]","onAction"]}],"antiPatterns":[{"pattern":"Showing raw error hex to users","why":"\"0x4e487b71...\" means nothing","instead":"Decode and display human message","severity":"critical"},{"pattern":"Generic \"Transaction failed\" without details","why":"User has no idea what went wrong","instead":"Parse error, show specific reason","severity":"critical"},{"pattern":"No recovery suggestions","why":"User stuck, doesn't know next step","instead":"Offer actions: \"Approve more\" or \"Get tokens\"","severity":"high"}],"onMonad":[{"aspect":"Error Format","ethereum":"ERC-6093 custom errors standard","monad":"Same error format, works identically","designImplication":"Same error handling code works"}],"keyTakeaways":["ERC-6093 = human-readable token errors","Always decode errors, never show raw hex","Show what user has vs what they need","Offer clear recovery actions","Common errors: InsufficientBalance, InsufficientAllowance"],"technicalNotes":"ERC-6093 defines custom errors: ERC20InsufficientBalance(sender, balance, needed), ERC20InsufficientAllowance(spender, allowance, needed), ERC721InsufficientApproval(operator, tokenId), etc. Decode using error selector (first 4 bytes) and ABI decode parameters. OpenZeppelin contracts v5+ use these errors."},"sources":[{"label":"Official specification","url":"https://eips.ethereum.org/EIPS/eip-6093","type":"official-spec"},{"label":"Discussion","url":"https://ethereum-magicians.org/search?q=ERC-6093","type":"discussion"}],"urls":{"canonical":"https://www.eipsfordesigners.com/standards/ERC-6093","markdown":"https://www.eipsfordesigners.com/standards/ERC-6093/content.md","agent":"https://www.eipsfordesigners.com/standards/ERC-6093/agent.md","api":"https://www.eipsfordesigners.com/api/standards/ERC-6093","official":"https://eips.ethereum.org/EIPS/eip-6093","discussion":"https://ethereum-magicians.org/search?q=ERC-6093"},"freshness":{"lastReviewed":"2026-04-05","lastUpdated":"2026-04-05"}}