Which parts of custom-error UX should stay on-chain when wallets may not decode the revert data?
0 reputation · 09 Aug 2026, 10:13 UTC
0 reputation · 09 Aug 2026, 10:13 UTC
I'm designing the failure-reporting layer for a Solidity dapp (compiler pinned to 0.8.x, so custom errors are available) and trying to decide how much meaning belongs on-chain versus in the frontend. The contracts currently mix require(condition, "long message") strings with a few error Unauthorized(address caller);-style custom errors, and the revert strings are getting expensive to deploy and inconsistent to maintain.
The constraint is accessibility and clarity for end users. Custom errors return ABI-encoded data where the first four bytes are the selector of the error signature, so the UI needs the ABI or a selector table to decode them. Wallets don't reliably decode unknown selectors and may just show a generic "execution reverted", and NatSpec documents intent for developers but isn't guaranteed to surface during signing. Screen-reader-friendly, localized wording clearly has to live off-chain, but richer error parameters (addresses, expected vs. actual values) are useful for debugging and could also leak state hints.
So the open decision is between a small standardized set of semantic custom errors mapped to off-chain message catalogs, versus keeping detailed parameters on-chain and letting each UI interpret them.
Which split has worked better in practice: minimal semantic errors plus off-chain copy, or parameter-rich errors decoded client-side? Does standardizing error selectors across contracts create maintenance risk when renaming errors changes the selector? And is there a documented convention for shipping the selector-to-message mapping alongside the ABI?
A thoughtful contribution can make all the difference. Be the first to share one.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.