CofheError objects on failure. This replaces the Result wrapper pattern used by cofhejs.
Catching errors
What a CofheError carries
EveryCofheError has:
code: aCofheErrorCodeenum value identifying the error typemessage: a human-readable description of what went wrong
isCofheError(err) to check if a caught error is a CofheError.
Common error codes
The
Permit* codes are gone. PermitNotFound and PermitInvalid are now ACPNotFound and ACPInvalid. The set also expanded: expiry, revocation, and scope denial each have their own code, so you no longer have to infer which one applied from the message.Error handling patterns
Encryption errors
Decryption errors
Distinguishing why an ACP is invalid
The decrypt flows callACPUtils.validate(acp) internally before talking to the Threshold Network. That helper enforces schema + signed + not-expired all at once, so when it fails the recovery path depends on which check tripped.
Use the non-throwing ValidationUtils.isValid helper from @cofhe/sdk/acps to pre-flight the active ACP and route based on the typed reason, which avoids the thrown error path entirely:
ValidationResult.error is the typed union 'invalid-schema' | 'expired' | 'not-signed' | null. See validating ACPs for the full helper surface.
If you prefer the throwing path:
ACPUtils.validate(acp) raises plain Errors with messages ACP is expired / ACP is not signed (or a Zod schema error). These are not wrapped in CofheError, so use err.message rather than an error code to branch.