Failed to decode candid

I got strange error message on my browser console. Failed to decode StoredContractVec: to record {\n friends : .... However, StoredContractVec has no fields named friends it seams candid is confusing two separate things.

Issue Fetching Initial Data from Backend:

_AgentError: Call Failed

  • Canister: bkyz2-fmaaa-aaaaa-qaaaq-cai
  • Method: get_initial_data (query)
  • Status: rejected
  • Code: CanisterError

Message:
IC0503: Error from Canister bkyz2-fmaaa-aaaaa-qaaaq-cai:
The canister called ic0.trap with the message:

Failed to decode StoredContractVec:
Custom Error: Failed to decode argument 0 from table0 to record:

{
  friends : vec record {
    sender : record {
      id : text;
      name : text;
      description : text;
      photo : blob;
    };
    confirmed : bool;
    receiver : record {
      id : text;
      name : text;
      description : text;
      photo : blob;
    };
  };
}

My code source

sh scripts/did.sh
dfx generate

I usually run these commands to generate the candid

the error start happening when I add this part of the code

pub fn get_list(user: Principal) -> Vec<Friend> {
        let mut list = vec![];
        FRIENDS_STORE.with(|friends_store| {
            let store = friends_store.borrow();
            if let Some(friends) = store.get(&user.to_string()) {
                list = friends.friends.clone();
            }
        });
        list
    }

To understand more about FRIENDS_STORE
it look like this


#[derive(Eq, PartialOrd, PartialEq, Clone, Debug, CandidType, Serialize, Deserialize)]
pub struct Friend {
    pub sender: User,
    pub receiver: User,
    pub confirmed: bool,
}

#[derive(Eq, PartialOrd, PartialEq, Clone, Debug, CandidType, Serialize, Deserialize, Default)]
pub struct FriendVec {
    pub friends: Vec<Friend>,
}


impl Storable for FriendVec {
    fn to_bytes(&self) -> Cow<[u8]> {
        Cow::Owned(Encode!(self).unwrap_or_else(|e| {
            ic_cdk::trap(&format!("Failed to encode StoredContractVec: {:?}", e));
        }))
    }

    fn from_bytes(bytes: Cow<[u8]>) -> Self {
        Decode!(bytes.as_ref(), Self).unwrap_or_else(|e| {
            ic_cdk::trap(&format!("Failed to decode StoredContractVec: {:?}", e));
        })
    }

    const BOUND: Bound = Bound::Bounded {
        max_size: 999999,
        is_fixed_size: false,
    };
}



thread_local! {

static FRIENDS_STORE: RefCell<StableBTreeMap<String, FriendVec, Memory>> = RefCell::new(
        StableBTreeMap::init(
            MEMORY_MANAGER.with(|m| m.borrow().get(MemoryId::new(6))),
        )
    );
}

Have you tried making Friends into a Option instead of returning an empty vec?

So, instead of:

  Friends : vec Friend;

This:

  Friends : opt vec Friend;

Also, worth considering: With the current implementation, you will allocate the max_size for each new FriendVec: 999999. Consider using a composite key to handle the one to many requirement.