Error: The Replica returned an error: code 5, message: "Canister trapped explicitly: could not perform self call"

I get this error when I’m trying to call an async class method from within a for loop of another async actor method.
Can anyone shed some light on this?

@claudio @diegop

Does it only happen if the for loop makes a larger number of iterations?

Can you share the code?

1 Like

I just tested this in the REPL and yes, you are correct. When you iterate 114 times, the Error pops up again.

You are probably hitting the problem that the output queue of a canister is bounded. When it is full, the canister cannot issue more calls, and the system will synchronously fail ic0.call_perform. These synchronous errors were added at point when Motoko already supported message calling, and there was no obvious way to add user-controlled error handling, besides treating it like any other out-of-resource error (e.g. memory allocation failure), and trap.

Traps cannot be caught directly, but indirectly if you wrap it another call (e.g. try await async { … }). Or maybe you can avoid the limit by sending only one message per call (plus one self-message), by adding a await async (); line that effectively yields to the scheduler.

1 Like

Thanks, this is very insightful!