-
Notifications
You must be signed in to change notification settings - Fork 6
Description
When using encode_args((arg1, arg2, arg3, ...)) in PocketIC tests to call canister methods with multiple arguments, the macro encodes the tuple as a single Candid record (table0) instead of encoding each argument separately. This causes deserialization failures in the receiving canister.
Environment
PocketIC version: 10.0.0
Candid version: 0.10.20
ic-cdk version: 0.18
Expected Behavior
Multiple arguments should be encoded as separate Candid arguments, matching the behavior of the real IC replica and dfx canister call.
Actual Behavior
encode_args((arg1, arg2, arg3, ...)) encodes the tuple as a single record argument, causing:
Fail to decode argument 0 from table0 to <expected_type>
Caused by: Subtyping error: Type mismatch
Reproduction
Canister method:
rust
#[update]
fn create_user(
user_type_str: String,
currency_str: String,
email: String,
first_name: String,
last_name: String,
principal_id: Option,
phone_number: Option,
) -> Result<User, String> { ... }
PocketIC test:
rust
use candid::encode_args;
let result = pic.update_call(
canister_id,
Principal::anonymous(),
"create_user",
encode_args((
"User".to_string(),
"UGX".to_string(),
"test@example.com".to_string(),
"John".to_string(),
"Doe".to_string(),
None::,
Some("+256700123456".to_string()),
)).unwrap(),
);
Error:
Panicked at 'called Result::unwrap() on an Err value: Custom(Fail to decode argument 0 from table0 to text
Caused by:
Subtyping error: text)'
Verification
The SAME code works perfectly on local IC replica:
bash
dfx canister call data_canister create_user
'("User", "UGX", "test@example.com", "John", "Doe", null, opt "+256700123456")'
✅ Returns: Ok(User { ... })
Workarounds Attempted
❌ Using Encode! macro: Encode!(&arg1, &arg2, ...).unwrap() - still encodes as record
❌ Using ic_cdk::call - deprecated and has same issue
❌ Passing struct instead - causes enum serialization issues
Impact
This makes it impossible to write PocketIC integration tests for canisters with multi-argument methods, forcing developers to:
Use local IC replica for all testing (much slower)
Artificially limit APIs to single-argument methods
Skip integration tests
Expected Fix
encode_args should encode tuples as separate Candid arguments (not a single record), matching real IC behavior.