Mismatching `@dfinity/agent` versions can cause hashing issues

Was running into the following error:

Uncaught (in promise) Error: Attempt to hash a value of unsupported type: dslea-eiaaa-aaaae-aaa3a-cai
    at hashValue (request_id.js?62bc:59)
    at eval (request_id.js?62bc:89)
    at Array.map (<anonymous>)
    at requestIdOf (request_id.js?62bc:87)
    at DelegationIdentity.transformRequest (delegation.js?f4b4:208)
    at HttpAgent.query (index.js?0682:170)
    at async caller (actor.js?126c:155)

The cause seems to be here:

// Line 30 of @dfinity/agent/esm/request_id.js
else if (value instanceof Principal) {
    return hash(value.toUint8Array());
}

I believe 0.10.0 added a new parameter _arr to the Principal class, so this value instanceof Principal returns falsy. Maybe @dfinity/agent should do a different check, like value.hasOwnProperty(toUint8Array) which would be less error prone here.

Actually, this isn’t a version mismatch problem. With uniformly versioned @dfinity/[email protected] across all of my dep’s, I was still seeing this error. The error is the result of (value instanceof Principal) returning falsy when the value and the Class being compared reach across npm dependencies. It seems to be the case that we end up with two unique initializations of the Principal class. Javascript object equality is based on location in memory, not a structural comparison.

@dfinity/agent should not use the instanceof operator. I’m sure this is causing issues right now for more people than just myself :grimacing:

This stack overflow offers some insight: node.js - Require and instanceof - Stack Overflow

And this SO details an interesting solution: javascript - Using `instanceof` on objects created with constructors from deep npm dependencies - Stack Overflow

It looks like someone might have been aware of this limitation, because the _isPrincipal parameter already exists on the Principal class and it does the job just fine. Perhaps it was deprecated for some other reason? :thinking:

1 Like

I do think this should be patched by Dfinity but if you’re running into issues, you can also patch the dependencies yourself. I did that in this commit using the patch-package npm.

I’ll try to get a fix for this into the next version of agent-js

3 Likes

I’ve created a PR fixing that. Not sure if what I did is the best solution. Feedback appreciated:

Wish I’d found this yesterday before beating my head against a wall for four hours! I suggested a bit of a different branch that looked for the _isPrincipal variable…I think your is simpler! But here it is in case it is worthwhile:

1 Like