I have found a couple of weird cases with encoding and decoding candid that has both recursive elements and blobs.
I get the following error:
throw new Error('type index out of range');
^
Error: type index out of range
at getType (node_modules/@dfinity/candid/src/idl.ts:1738:13)
at buildType (node_modules/@dfinity/candid/src/idl.ts:1770:26)
at node_modules/@dfinity/candid/src/idl.ts:1813:17
at Array.forEach (<anonymous>)
at Object.decode (node_modules/@dfinity/candid/src/idl.ts:1811:12)
at Object.<anonymous> (src/index.ts:23:5)
at Module._compile (node:internal/modules/cjs/loader:1256:14)
at Module.m._compile (node_modules/ts-node/src/index.ts:1618:23)
at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
at Object.require.extensions.<computed> [as .ts] (node_modules/ts-node/src/index.ts:1621:12)
From running the following code.
import { IDL } from '@dfinity/candid';
const node = IDL.Rec();
const recBlob = IDL.Rec();
const recVarBlob = IDL.Rec();
recBlob.fill(IDL.Vec(IDL.Nat8));
recVarBlob.fill(
IDL.Variant({
Blob: IDL.Vec(IDL.Nat8)
})
);
node.fill(
IDL.Variant({
Node: node,
Leaf: recBlob,
ANode7: recVarBlob
})
);
const encodedBroken = IDL.encode([node], [{ Leaf: new Uint8Array() }]);
IDL.decode([node], encodedBroken);
There are a number of odd things I can do to this code snippet to make it work. The oddest one is if I rename ANode7 to ANode, Node7 or ode7 it works fine, but shortening it even further to de7 or even to just e causes it to break again.
Removing some of the recursion that isn’t strictly needed in this particular case also causes the error to vanish. For example
const recBlob = IDL.Vec(IDL.Nat8)
Or if I change both recBlob and recVarBlob to be:
const recBlob = IDL.Rec();
const recVarBlob = IDL.Rec();
recBlob.fill(IDL.Vec(IDL.Nat8));
recVarBlob.fill(IDL.Vec(IDL.Nat8));
That also works.
It’s kind of weird and any insight into why this is happening would be greatly appreciated.