ICRC-1 transfer errors

Is there a detailed description of the errors in

type TransferError = variant {
    BadFee : record { expected_fee : nat };
    BadBurn : record { min_burn_amount : nat };
    InsufficientFunds : record { balance : nat };
    CreatedInFuture: record { ledger_time : Timestamp };
    Duplicate : record { duplicate_of : nat };
    GenericError : record { error_code : nat; message : text };

What exactly do they mean and in what situations can they arise? For example, what defines a duplicate? And which situations fall under TemporarilyUnavailable?

My second question is about upgradability. Can an implementation add variants to this? My understanding is that it can not because that would create a supertype in a return type and general ICRC-1 clients wouldn’t be able to interact with that implementation. How do we deal with this? I expect that implementations can have idiosyncratic errors.


Any ideas?

I suppose as the list can’t be extended that we have to use GenericError. Different ledger implementations just have to agree on what the error codes in GenericError mean. Conflicting behaviour would be bad for clients. We’ll have to track these error codes somewhere publicly.

I think the idea was to use generic error going forward. Probably these should have been similar to metadata and been more extensible.

I’m bumping this thread because it’d be good to have some clear definitions of what these different errors mean and when they can occur. This’ll help in presenting actual meaningful errors to users…


They’re all clearly defined in ICRC-1. ICRC-1/README.md at main · dfinity/ICRC-1 · GitHub

TemporarilyUnavailable appears not to be.

TemporarilyUnavailable and GenericError are states that might occur without any logical predicate.

So from a callers point of view these errors might arbitrarily occur for unspecified reasons. A reasonable error handling logic would be to retry or abandon.