Error: “Impossible to convert undefined to Principal.”

To test deployment on the mainnet, I have deployed a very simple project where the frontend is written in JavaScript and the backend in Motoko. The project works well in the local development environment.

After deployment, the frontend canister is located at https://gn23t-ciaaa-aaaag-qcgsq-cai.icp0.io/. While running this canister, I encountered an error, and the message in the JavaScript console reads:

(anonymous) @ index.js:2
index.js:2 start checking balance
index.js:2 Uncaught (in promise) Error: Impossible to convert undefined to Principal.
at B.from (index.js:2:120970)
at index.js:2:244738
at kt.n [as checkBalance] (index.js:2:245662)
at Ft (index.js:2:246452)
at index.js:2:246619

The error occurred when the index.html is loaded, and a function Update in index.js is activated. The Update function is as follows:

async function update() {
console.log(“start checking balance”);
const currentAmount = await dbank.checkBalance();
console.log(“done checking balance.”);
document.getElementById(“value”).innerText = Math.round(currentAmount * 100) / 100;
};

As you can see, the message “start checking balance” is displayed in the console, but not the “done checking balance.”, meaning, the error occurred when the backend function dbank.checkBalance() was called.

The backend canister is accessible via the Candid interface at:
https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.ic0.app/?id=gk35h-pqaaa-aaaag-qcgsa-cai

The current dfx version is 0.14.3. The above error occurred when the dfx version in dfx.json is set to 0.13.1. When I changed the dfx version in dfx.json to be 0.14.3, I encountered a different error, as below:

(anonymous) @ index.js:2
index.js:2 start checking balance
index.js:2 Invalid asm.js: Unexpected token
index.js:2 Uncaught (in promise) Error: Failed to parse
at TA._decode (index.js:2:56852)
at TA.decodeFirst (index.js:2:56967)
at LA (index.js:2:149652)
at XA.query (index.js:2:155023)
at async index.js:2:244802
at async Ft (index.js:2:246420)

I have struggled with this deployment problem for a couple of days. I have read many posts, including:

I have tried suggestions by @kpeacock to check whether canisters are set up correctly in webpack.config.js via EnvironmentPlugin, matching process.env variables in the generated index.js in the folder of declarations. To ensure the canisters are given correct names, I have tried uncommenting lines 99, 101, and 102 in webpack.config.js, but I still encountered the same errors. Specifically, “Failed to parse” under dfx version 0.14.3 and “Impossible to convert undefined to Principal” under dfx version 0.13.1.

I have read many posts by @matthewhammer, @claudio, @Severin about deploying IC projects and about the new dfx release. I have also read dfx new release notes. Despite these efforts, I can’t figure out how to fix the problem.

The project codes are accessible at GitHub - yu970253/deploymentTest.

Can anybody help solve this problem? Best regards!

Anytime I’ve encountered this error it has to do with the env vars not being initialized correctly.

When you run dfx (this is a newer feature of dfx so make sure it’s up to date) and it builds canisters, it’ll generate a .env for you containing all the canister ids required by the canister being built. It’ll also overwrite existing entries–so the trick is to build the last canister of your project (such as frontend) with all the other canisters as its dependents (so the ids will be included).

Not sure if it will generate the .env by default yet, but to make it so add to your dfx.json:

 // rest of config
  "version": 1, // just to see where in the file to put it
  "output_env_file": ".env",
}

Then at the beginning of your webpack config (like you had it)

const dotenv = require("dotenv");
dotenv.config();
// all of the env vars from .env will be spread on process.env
// rest of config

And then you can console.log(process.env.<a canister id>) (or throw if it’s null, etc) to verify they’ve been loaded. Unless webpack is supposed to do this for you? Idk I use vite.

The error, iirc, is because as the env vars are not loaded, you’re passing undefined as process.env.*, and undefined can’t be converted to a principal…

@icaten, thank you very much for your attention and feedback. I have tried your suggested changes, but still got the same errors, as below:

index.js:2 process.env.CANISTER_ID_dbank_assets gn23t-ciaaa-aaaag-qcgsq-cai
index.js:2 process.env.CANISTER_ID_dbank gk35h-pqaaa-aaaag-qcgsa-cai
index.js:2 start checking balance
index.js:2 Uncaught (in promise) Error: Impossible to convert undefined to Principal.
at B.from (index.js:2:120970)
at index.js:2:244738
at kt.n [as checkBalance] (index.js:2:245662)
at Ft (index.js:2:246609)
at index.js:2:246776

With your suggestions, the dfx.json is as below:
// rest of config
“dfx”: “0.13.1”,
“networks”: {
“local”: {
“bind”: “127.0.0.1:8000”,
“type”: “ephemeral”
}
},
“version”: 1,
“output_env_file”: “.env” //added
}

The webpack.config.js is as below:
const dotenv = require(“dotenv”); //added
dotenv.config(); //added
const path = require(“path”);
const webpack = require(“webpack”);
//rest of config

I have added console.log in the index.js file to check whether the process.env. are built, so the update() function in the index.js file is as below:

async function update() {
console.log(“process.env.CANISTER_ID_dbank_assets”, process.env.CANISTER_ID_dbank_assets); //added
console.log(“process.env.CANISTER_ID_dbank”, process.env.CANISTER_ID_dbank); //added

console.log(“start checking balance”);
const currentAmount = await dbank.checkBalance();
console.log(“done checking balance.”);
document.getElementById(“value”).innerText = Math.round(currentAmount * 100) / 100;
};

Now the .env file in the root folder has content as below:
DFX_VERSION=‘0.13.1’
DFX_NETWORK=‘ic’
CANISTER_CANDID_PATH_dbank=‘/Users/Daniel/ic-projects/dbank/.dfx/ic/canisters/dbank/dbank.did’
CANISTER_ID_dbank_assets=‘gn23t-ciaaa-aaaag-qcgsq-cai’
CANISTER_ID_dbank=‘gk35h-pqaaa-aaaag-qcgsa-cai’
CANISTER_ID=‘gn23t-ciaaa-aaaag-qcgsq-cai’
CANISTER_CANDID_PATH=‘/Users/Daniel/ic-projects/dbank/.dfx/ic/canisters/dbank_assets/assetstorage.did’

I noticed that the canister variables generated are CANISTER_ID_dbank and CANISTER_ID_dbank_asset. That is, upper case for CANISTER_ID and lower case for canister names. Is that a problem?

I am also thinking how to implement your suggestion: building the final canister of the project (such as the frontend) with all the other canisters as its dependencies, thus ensuring that their IDs are included. Could you please provide some further explanation on this? I would like to better understand the steps involved in accomplishing this.

I have submitted the changed codes at GitHub - yu970253/deploymentTest.

Since the errors still exist, what else can I do? Thank you very much!

I’d recommend you try with the latest version of dfx. Maybe there was something fixed. dfx upgrade will do the trick, but you have to remove "dfx": "0.13.1" from your dfx.json

You can specify canister dependencies like this: https://github.com/dfinity/sdk/blob/master/src/dfx/assets/new_project_motoko_files/dfx.json#L13-L15

Should be fine, we have tests for such things in dfx

@Severin, thank you very much for your suggestions! I ran “dfx upgrade” just now and verified that the version remains 0.14.3. I also removed “dfx”: “0.13.1” from dfx.json as you suggested. Now I got an error message as below:
image

Do you have any suggestions or ideas on how to resolve this issue? Thanks!

Can you try this? https://github.com/dfinity/sdk/blob/master/docs/migration/dfx-0.14.0-migration-guide.md#webpack--bundler-migration

It would probably be easier to create a new project with the latest dfx, then manually copy the frontend assets and backend motoko files, and bypass whatever the presumbly deprecated scripting is going on in this repo (it looks like you “forked” it from a project that was created many dfx versions earlier).

@icaten @Severin, great news! After struggling for over one week, I finally solved the problem. By changing the “scripts” section of package.json as shown below, the project can now be deployed online and is performing as expected.
image

What I learned from this experience is that in addition to having good codes for both frontend and backend, it’s crucial to ensure that the project setup is correct.

Thank you very much for your warm-hearted support! Best regards!

1 Like

Great for sticking with it, good luck on your endeavors.