ProtocolError is the shared error enum defined in crates/lily-common/src/lib.rs. All deployable contracts use these typed codes instead of raw panic messages. This document lists each variant, its numeric code, where it is raised, and example conditions that trigger it.
| Code | Variant | Description | Raise sites |
|---|---|---|---|
| 1 | AlreadyInitialized |
initialize was called on a contract that already has Initialized set. |
identity::initialize, payments::initialize, protocol::initialize, wallet::initialize |
| 2 | NotInitialized |
A state-mutating or state-reading function was called before initialize. |
All ensure_initialized helpers in identity, payments, protocol, wallet |
| 3 | Unauthorized |
Reserved for auth failures; currently the contracts rely on Address::require_auth() for authorization, so this code is not actively raised. |
— |
| 4 | InvalidInput |
A caller-provided value violates a basic invariant (empty, non-positive, disabled, etc.). | identity::update_profile (profile inactive), payments::create_intent (amount ≤ 0), wallet::bind_wallet/wallet::update_spend_limit (spend_limit ≤ 0 or binding disabled) |
| 5 | FeeBpsTooHigh |
A fee value exceeds MAX_BPS (10,000 = 100%). |
protocol::initialize, protocol::set_fee_bps, payments::initialize (via require_valid_bps) |
| 6 | AlreadyExists |
A unique record already exists and would be overwritten. | identity::register (agent profile already registered) |
| 7 | MissingRecord |
A required storage record was not found. | identity::get_profile_internal, payments::get_intent_internal, wallet::get_binding_internal |
| 8 | PaymentAlreadyFinalized |
A payment intent is no longer Pending when settle_intent or cancel_intent is called. |
payments::settle_intent, payments::cancel_intent |
| 9 | WalletAlreadyBound |
An attempt to bind a wallet to an agent that already has an enabled binding. | wallet::bind_wallet |
AlreadyInitialized—initializecalled twice.NotInitialized— any external function called beforeinitialize.AlreadyExists—registercalled for anagentthat already has aProfileentry.InvalidInput—update_profilecalled on a profile whoseactiveflag isfalse.MissingRecord—get_profile/update_profile/deactivatereferences an unregisteredagent.
AlreadyInitialized—initializecalled twice.NotInitialized— any external function called beforeinitialize.InvalidInput—create_intentwithamount <= 0; emptymemo/settlement_referenceraise viarequire_non_empty(which itself usesInvalidInput).FeeBpsTooHigh—initializewithfee_bps > MAX_BPS.MissingRecord—settle_intent/cancel_intent/get_intentreferences an unknownintent_id.PaymentAlreadyFinalized—settle_intentorcancel_intentcalled on an intent whose status is alreadySettledorCancelled.
AlreadyInitialized—initializecalled twice.NotInitialized—get_config,set_fee_bps,set_treasury,transfer_admincalled beforeinitialize.FeeBpsTooHigh—initializeorset_fee_bpswithfee_bps > MAX_BPS.
AlreadyInitialized—initializecalled twice.NotInitialized— any external function called beforeinitialize.InvalidInput—bind_wallet/update_spend_limitwithspend_limit <= 0, orupdate_spend_limiton a disabled binding.WalletAlreadyBound—bind_walletcalled for an agent whose existing binding hasenabled == true.MissingRecord—update_spend_limit,set_enabled, orget_bindingreferences an agent with noBindingentry.
MAX_BPSis defined as10_000inlily-commonand represents 100% in basis points.require_non_emptymaps zero-length strings toInvalidInput.- Authorization itself is enforced by
Address::require_auth();ProtocolError::Unauthorizedis reserved for future use.