Build Error with imported Actor Class

The following import pattern doesn’t seem to work. I can’t quite figure out why.

My hope here was to deploy the canisters and have access to the initializer object so I know who the “owner” is.

//usernamesBucket.mo
shared({ caller = initializer }) actor class() {
    
};
//main.mo
import Usernames "canister:usernamesBucket";

shared({ caller = initializer }) actor class() {
    public query func greet() : async Text {
        return "Hello world";
    };
};
//dfx.json
{
  "canisters": {
    "usernamesBucket": {
      "main": "src/backend/usernamesBucket.mo",
      "type": "motoko"
    },
    "backend": {
      "main": "src/backend/main.mo",
      "type": "motoko",
      "dependencies": [
        "usernamesBucket"
      ]
    },
    "frontend": {
      "dependencies": [
        "usernames"
      ],
      "frontend": {
        "entrypoint": "src/frontend/public/index.js"
      },
      "source": [
        "src/frontend/assets",
        "dist/frontend/"
      ],
      "type": "assets"
    }
  },
  "defaults": {
    "build": {
      "packtool": ""
    }
  },
  "dfx": "0.6.20",
  "networks": {
    "local": {
      "bind": "127.0.0.1:8000",
      "type": "ephemeral"
    },
    "tungsten": {
      "providers": [
        "https://gw.dfinity.network"
      ],
      "type": "persistent"
    }
  },
  "version": 1
}

Log

The build step failed for canister 'rwlgt-iiaaa-aaaaa-aaaaa-cai' with an embedded error: The command '"/home/steve/.cache/dfinity/versions/0.6.20/moc" "/home/steve/src/dfinity-vue-starter/src/backend/main.mo" "-o" "/home/steve/src/dfinity-vue-starter/.dfx/local/canisters/backend/backend.did" "--idl" "--actor-idl" "/home/steve/src/dfinity-vue-starter/.dfx/local/canisters/idl/" "--actor-alias" "backend" "rwlgt-iiaaa-aaaaa-aaaaa-cai" "--actor-alias" "usernamesBucket" "r7inp-6aaaa-aaaaa-aaabq-cai" "--package" "base" "/home/steve/.cache/dfinity/versions/0.6.20/base"' failed with exit status 'exit code: 2'.
Stdout:

Stderr:
Fatal error: exception "Assert_failure mo_idl/idl_to_mo.ml:107:9"
Raised at file "mo_idl/idl_to_mo.ml", line 107, characters 9-21
Called from file "pipeline/pipeline.ml", line 336, characters 20-67
Called from file "lang_utils/diag.ml", line 30, characters 27-30
Called from file "lang_utils/diag.ml", line 46, characters 20-25
Called from file "lang_utils/diag.ml", line 30, characters 27-30
Called from file "lang_utils/diag.ml", line 30, characters 27-30
Called from file "pipeline/pipeline.ml" (inlined), line 340, characters 20-42
Called from file "pipeline/pipeline.ml", line 342, characters 47-63
Called from file "pipeline/pipeline.ml", line 350, characters 21-52
Called from file "lang_utils/diag.ml", line 30, characters 27-30
Called from file "lang_utils/diag.ml", line 30, characters 27-30
Called from file "pipeline/pipeline.ml", line 430, characters 27-71
Called from file "exes/moc.ml", line 132, characters 24-53
Called from file "exes/moc.ml", line 186, characters 4-23

This isn’t an issue with your initializer object, it seems to be an issue with the class keyword in usernamesBucket.mo. And it only throws the error when it’s imported.

It might be a bug, this does seem like strange behaviour. @hansl

1 Like

Gotcha, in the event this is a bug, is there another way to access the creator of the actor that I might be able to use as a work around? Hoping to work on a project this weekend.

I should have added, importing the usernamesBucket canister with the following signature works:

//usernamesBucket.mo
actor {
    
};

The simplest way is to just hard code it for now:

//usernamesBucket.mo

import Principal "mo:base/Principal";

actor {
    let initializer: Principal = Principal.fromText("<your_id>");
};

You can get <your_id> from the terminal:

dfx identity get-principal

1 Like

Hi Steve,

The compiler should not be crashing like this, but just be reporting an error instead. We’ve filed an issue.

The error is that you are trying to import a canister (actor), but the reference actually refers to an canister/actor class.

We can’t deploy canister classes to the network yet, just instances of canister classes, and you can’t import canister classes yet either, just canisters.

However, you can actually import the code as a Motoko library (not a canister reference), provided you then instantiate the actor class programmatically from Motoko (not dfx). The manual contains an example of doing this, but I’m not sure if that suites your scenario.

I suspect Ori’s solution might be better for your use case.

4 Likes

Gotcha, that makes sense. Thanks Claudio!