Dfx.json actor with mandatory arguments

How do you handle your actors that need arguments to be deployed in dfx.json?
Do you exclude such actors (if possible) of the config or is there a way to specify an argument in the json file?
And what if the argument is secret?

In my project I’ve got two canisters, one actor that needs no arguments and another one that need one.

I can deploy these both separately

$ dfx deploy --argument 'secret' canister1
$ dfx deploy canister2

but if I deploy both at the same time then i get an error because the argument is not set:

$ dfx deploy

...

Installing canisters...
Error: Invalid data: Expected arguments but found none.

You can deploy both with that argument; as for deploying them with different arguments, we’ve got an internal ticket about that.
However remember that dfx-deploy does what it does and doesn’t do any more. If you need scripting around it, write a script.

1 Like

I have a PR ready that adds a schema for dfx.json. Have a look at these lines: sdk/dfx-json-schema.json at ca578a30ea27877a7222176baea3a6aa368ca6e8 · dfinity/sdk · GitHub, it should be quite useful for that situation.

1 Like

Thanks both of your for the answers. Kind of answer it, I’ll have to write a script :wink:.

But now I got all the info and the dfx description is awesome!

Is it explained anywhere what exactly the “args” property in the schema does? From your post and from the description in the schema (“This field defines a static argument to use when deploying the canister.”) it sound like it becomes a deploy argument just like dfx deploy --argument <args> on the command line. But when I run it then the value seems to be passed to moc upon running dfx deploy and moc throws an error. How do I use the “args” property as a deploy argument?

Correct, that’s the intention.

That sounds like a bug. Do you have a reproduction handy?

Here’s an example. I run dfx new hello to get a new project. The actor does not take any arguments, but it still works if I supply arguments on the command line with an option like --argument=() or even --argument=(0) due to subtyping still works. But if I add it to dfx.json like this:

I remove the frontend canister from it so my dfx.json looks like this:

    "hello_backend": {
      "main": "src/hello_backend/main.mo",
      "type": "motoko",
      "args" : "()"
    }
 

then dfx build produces an error that looks like this:

Failed to build Motoko canister 'hello_backend'.: Failed to compile Motoko.: Failed to run 'moc'.: The command '"/Users/timo/.cache/dfinity/versions/0.12.0-beta.2/moc" "/Users/timo/ic-projects/args/hello/src/hello_backend/main.mo" "-o" "/Users/timo/ic-projects/args/hello/.dfx/http___localhost_64320/canisters/hello_backend/hello_backend.wasm" "-c" "--debug" "--idl" "--stable-types" "--public-metadata" "candid:service" "--actor-idl" "/Users/timo/ic-projects/args/hello/.dfx/http___localhost_64320/canisters/idl/" "--actor-alias" "hello_backend" "rrkah-fqaaa-aaaaa-aaaaq-cai" "--package" "base" "/Users/timo/.cache/dfinity/versions/0.12.0-beta.2/base" "()"' failed with exit status 'exit status: 1'.
Stdout:

Stderr:
(): No such file or directory

As we can see () ended up on the moc command line if you scroll all the way to the right.

Thanks for the details. This is either a documentation bug or a dfx bug. I’ll have to consult the team for that.

Right now, args just adds arguments during the compilation step. Either this is a bug, or I misunderstood the purpose of the field and wrote the documentation wrong.

My bad, I wrote the docstring wrong. Fixing it.

It would actually be really useful to be able to specify a file containing arguments. Why a file? Because then the arguments can be created by the build command, or modified by the user, without having to change dfx.json. Is there any chance that we can get something like a canister_args_file in dfx.json? :slight_smile: :pray:

I like the idea! Feature request created over here. More upvotes on the GH discussion = easier for me to push for the feature