Error When Creating Dynamic Canisters in Actor Class with Insufficient Cycles

I need to dynamically create canisters within an actor class in Motoko. Specifically, I am trying to instantiate a Bucket canister using the following pattern:

let b = await Bucket.Bucket(k, n);

The goal is to create new Bucket canisters as needed, which are managed by a main actor (Main). However, I am encountering an issue related to cycle management when attempting to invoke this functionality via the putBucket function. Below is the relevant code:


actor class Bucket(n: Nat, i: Nat) = this {

    type key = Nat;
    type value = Text;

    let map = Map.RBTree<key, value>(Nat.compare);

    public func put(k: key, v: value): async(value) {
       assert((k % n) == i);
       map.put(k, v);
       v
    }
};


actor Main {
   let n: Nat = 10;
   type key = Nat;
   type value = Text;

   type BUCKET = Bucket.Bucket;

   let buckets: [var ?BUCKET] = Array.init(n, null);

   public func putBucket(k: key, v: value): async(value) {
      let _i = (k % n );
      let bucket = switch(buckets[_i]) {
          case (null) {
               let ava = Cycle.available();
               Debug.print("Available: " # debug_show(ava));
               Cycle.add<system>(10_000_000_000);  
               let b = await Bucket.Bucket(k, n);
               buckets[_i] := ?b;
               b;
          };
          case (?buc) buc;
      };
      await bucket.put(k, v);
   }
};

To test the canister creation and data storage, I am calling the putBucket function using the following command:

dfx canister call --wallet $(dfx identity get-wallet) Main putBucket '(1, "usman")' --with-cycles 10_000_000_000

Unfortunately, each time I run this, I receive the following error:

Error: Failed to do wallet call.
Caused by: An error happened during the call: 4: Canister installation failed with `Canister by6od-j4aaa-aaaaa-qaadq-cai is out of cycles: please top up the canister with at least 3_846_202_560 additional cycles`.

A few points to note:

  • Each time the error occurs, the canister ID changes, so I am unable to predict or top up cycles for the new canister before it’s created.
  • I am using the --with-cycles 10_000_000_000 flag, but the error still occurs, suggesting that the cycles are not being properly allocated or there is another issue at play.

I would appreciate some guidance on the following:

  1. What might be causing this error related to cycles when attempting to create dynamic canisters?
  2. What is the correct way to handle cycle allocation for dynamically created canisters in Motoko?
  3. Is there a recommended approach or resource that explains the flow for dynamic canister creation and cycle management?

Thank you in advance for your assistance! Any advice or direction to relevant resources would be greatly appreciated.

You’re attaching 10B cycles. Creating a canister on mainnet costs 100B, and you need to add some such that it doesn’t run out of cycles immediately. I suggest you add at least 200B cycles to the call

1 Like

Thank you for the solution—it worked perfectly! Increasing the cycles to 200B resolved the issue.

Could you also share any resources or documentation that explain cycle costs and management for dynamic canister creation? I’d love to learn more for future use.

Exact costs are here, some more about estimating fees is here.

I don’t really know about documentation about dynamic canister creation. They are convenient, but very hard to upgrade AFAIU. For anything but temporary canisters I am not sure if I would recommend them.
Relevant thread from today about cycles management: How do multi-level Canisters manage cycles recharge?

1 Like