Sui.

Post

Share your knowledge.

HaGiang.
Jun 15, 2025
Expert Q&A

what is the point of errors with #[error] attribute?

They are still are numbers in string both in wallets/explorers/move modules.

  • Sui
2
2
Share
Comments
.

Answers

2
0xduckmove.
Jun 15 2025, 09:24

The #[error] attribute in Move (especially in Move 2024) allows you to define error constants as human-readable messages (as vector), not just as numbers. This is a new feature that improves developer and user experience.

#[error]
const ENotAuthorized: vector<u8> = b"The user is not authorized to perform this action";

public fun update_value(user: &mut User, value: u64) {
    assert!(user.is_authorized, ENotAuthorized);
}

For more details, see the Move Book: https://move-book.com/move-basics/assert-and-abort.html#error-messages

2
Best Answer
Comments
.
harry phan.
Jun 30 2025, 07:55

The #[error] attribute in Move (especially in Move 2024) allows you to define error constants as human-readable messages (as vector), not just as numbers. This is a new feature that improves developer and user experience.

Why use #[error]?

  • Descriptive error messages: Instead of just returning a number (like abort 1), you can return a string message that explains what went wrong.
  • Better debugging: Developers and users can see a clear reason for the failure, making it easier to understand and fix issues.
  • Improved UX: Wallets, explorers, and dApps can display meaningful error messages to users, not just error codes.

Examples

#[error]
const ENotAuthorized: vector<u8> = b"The user is not authorized to perform this action";

public fun update_value(user: &mut User, value: u64) {
    assert!(user.is_authorized, ENotAuthorized);
}

When the assertion fails, the error message "The user is not authorized to perform this action" can be shown, instead of just a number.

Are errors still numbers in wallets/explorers?

  • Old style: Errors were just numbers (e.g., abort 1), and wallets/explorers would only show the code.
  • With #[error]: If the wallet/explorer supports Move 2024 error messages, it can decode and display the string. If not, it may still show the raw bytes or a number.

So, the #[error] attribute is about making error handling more expressive and user-friendly, but full support depends on the tools (wallets, explorers) updating to display these messages.

For more details, see the Move Book: Error Messages.

Would you like to see how to define both numeric and string errors in a Move module? Or are you interested in how to make your dApp or wallet display these messages?

How to Decode #[error] Messages

When you see an error in a wallet, explorer, or log, it might look like a number or a string of bytes (e.g., 0x5468652075736572206973206e6f7420617574686f72697a656420746f20706572666f726d207468697320616374696f6e).

1. If you see a number (e.g., 1):

  • This is a legacy error code. You need to look up the code in the module’s source to see what it means.

2. If you see a hex string (e.g., 0x546865...):

  • This is a UTF-8 encoded error message as a vector of bytes.
To decode:
  • Remove the 0x prefix.
  • Convert the hex string to bytes.
  • Interpret the bytes as a UTF-8 string.

Example

Suppose you see this error: 0x5468652075736572206973206e6f7420617574686f72697a656420746f20706572666f726d207468697320616374696f6e

  • Remove 0x.
  • Convert hex to ASCII/UTF-8:
    • 54 68 65 20 75 73 65 72 20 69 73 20 6e 6f 74 20 61 75 74 68 6f 72 69 7a 65 64 20 74 6f 20 70 65 72 66 6f 72 6d 20 74 68 69 73 20 61 63 74 69 6f 6e
  • This decodes to:
    • The user is not authorized to perform this action

How to decode in code (Rust, JS, Python, etc.):

  • Rust:

let hex = "5468652075736572206973206e6f7420617574686f72697a656420746f20706572666f726d207468697320616374696f6e"; let bytes = hex::decode(hex).unwrap(); let message = String::from_utf8(bytes).unwrap(); println!("{}", message);

  • JavaScript:

const hex = "5468652075736572206973206e6f7420617574686f72697a656420746f20706572666f726d207468697320616374696f6e"; const message = Buffer.from(hex, "hex").toString("utf8"); console.log(message);

  • Python:

hex_str = "5468652075736572206973206e6f7420617574686f72697a656420746f20706572666f726d207468697320616374696f6e" message = bytes.fromhex(hex_str).decode("utf-8") print(message)

Summary:

  • If you see a number, look it up in the code.
  • If you see a hex string, decode it as UTF-8 to get the human-readable error.

If you want a quick online tool, just search for “hex to text converter” and paste your hex string.

Would you like a script or tool for decoding these errors automatically? Or do you want to know how to make your own errors more readable in your Move code?

1
Comments
.

Do you know the answer?

Please log in and share it.

Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.

400Posts559Answers
Sui.X.Peera.

Earn Your Share of 1000 Sui

Gain Reputation Points & Get Rewards for Helping the Sui Community Grow.

Reward CampaignJuly