Vesting · Errors · 12@tokenops/sdk/fhe-vesting

Vesting errors you can catch by class.

Catch these by class reference; each carries the offending value (vestingId, unlocksAt, feeType, etc.) so your UI can render a message specific to the failure mode.

For the catch-ladder pattern + how SDK-level and viem-passthrough errors fit alongside these, read Concepts › Typed errors + recovery.

ClassWhen thrownRecovery
VestingNotFoundErrorvestingId does not exist on this manager clone.User is likely on the wrong manager. Offer the correct address; the SDK exposes useRecipientVestings to discover their vestings on a manager.
ClaimLockedErrorThe schedule’s timelock has not elapsed yet (block timestamp < startTimestamp + timelock).err.context.unlocksAt is the Unix timestamp the lock lifts. Render a countdown. useClaim
VestingExpiredErrorSchedule passed its end timestamp and any final claim window closed.Nothing to claim. Offer to fall through to the next schedule, or surface 'fully claimed'.
VestingRevokedErrorOperator already revoked this vesting; useClaim/usePartialClaim on a revoked schedule.Read state via useVestedAmount / useGetClaimableAmount — both honor revocation. Render 'revoked' instead of a claim button.
VestingNotRevocableErroruseRevokeVesting called on a vesting created with isRevocable=false.Revocability is set at vesting open and immutable. The UI should hide the revoke action unless useVestingMetadata.isRevocable is true.
TransferAlreadyPendingErroruseInitiateVestingTransfer called while a pending transfer already exists for this vestingId.Check usePendingVestingTransfer first; cancel the prior one before opening a new transfer.
TransferExpiredErroruseAcceptVestingTransfer called after the transfer's expiry timestamp.err.context.expiredAt shows when the offer lapsed. Initiator must call useInitiateVestingTransfer again to issue a fresh offer.
AccessDeniedErrorCaller lacks the role the call requires (VESTING_CREATOR_ROLE, REVOKER_ROLE, PAUSER_ROLE, DISCLOSURE_ADMIN_ROLE, …).err.context.role is the bytes32 role identifier. Check useHasRole + the role-constants table on the manager.
BatchTooLargeErroruseBatchCreateVesting passed more entries than the manager allows in a single tx.Chunk the batch. The on-chain cap is encoded in the contract; surface a 'too many entries' UI rather than the raw error.
FeatureDisabledErrorOperator called a feature the manager wasn't configured for (e.g. split on a non-split manager).Configuration flags are immutable at clone-time. Hide the action in the UI if useManagerConfig flags it disabled.
InsufficientBalanceErroruseCreateVesting: encrypted source balance is too low for the requested amount.Re-read the encrypted balance with useDecryptedHandle; surface the cap to the user before they submit.
MissingEncryptorErrorA write hook that encrypts client-side ran without an encryptor injected.Pass encryptor in ManagerHookOptions (parent scope) or via args.encryptor on the mutate call. See /concepts/encryptor.
Each class extends the SDK's base TokenOpsSdkError and carries the offending values under err.context — render specific messages instead of generic "transaction failed."Read the catch ladder