I have found a small regression in how rust canisters handle vecs of null or emptyish objects. Everything works fine in ic-cdk-0.9.2 but breaks in ic-cdk-0.10 and is still broken in 0.12.0.
When I try to run a command like
dfx canister call null_vecs_backend vec_of_null '(vec{null;null;null})'
I get the following error:
The replica returned a replica error: Replica Error: reject code CanisterError, reject message Canister be2us-64aaa-aaaaa-qaabq-cai trapped explicitly: failed to decode call arguments: Custom(Fail to decode argument 0 from table0 to vec record { null; null; null }
Caused by:
vec length of zero sized values too large), error code None
Here is a simple rust canister that exhibits the problem:
A snippet from my Cargo.toml
# Works
# candid = "0.8"
# ic-cdk = "0.9.2"
# Doesn't work
# candid = "0.9.0"
# ic-cdk = "0.10.0"
# Still doesn't work
candid = "0.10.0"
ic-cdk = "0.12.0"
My full rust canister
use candid::CandidType;
use serde::Deserialize;
#[derive(CandidType, Deserialize)]
pub struct EmptyRec {}
#[derive(CandidType, Deserialize)]
pub struct NullRec {
null_field: (),
}
//dfx canister call null_vecs_backend vec_of_null '(vec{null;null;null})'
#[ic_cdk::query]
fn vec_of_null(_params: Vec<()>) -> () {}
//dfx canister call null_vecs_backend vec_of_empty_record '(vec{record{}; record{}})'
#[ic_cdk::query]
fn vec_of_empty_record(_params: Vec<EmptyRec>) -> () {}
//dfx canister call null_vecs_backend vec_of_null_record '(vec{record{null_field=null: null}; record{null_field=null}})'
#[ic_cdk::query]
fn vec_of_null_record(_params: Vec<NullRec>) -> () {}
//dfx canister call null_vecs_backend vec_of_null_tuple '(vec{record{null; null; null}; record{null; null; null}})'
#[ic_cdk::query]
fn vec_of_null_tuple(_params: Vec<((), (), ())>) -> () {}
Note: vec of empty tuple doesn’t work either, but I’m not sure how to represent that in rust, so it’s not in this example.
If these vecs have no elements then the call will go through just fine
ie this works
dfx canister call null_vecs_backend vec_of_null '(vec{})'
while this does not
dfx canister call null_vecs_backend vec_of_null '(vec{null})'
Does anyone have any insight into what is causing this problem?