hoppscotch/hoppscotch · error · Error
unwrapKey requires all arguments: format, wrappedKey, unwrap
Error message
unwrapKey requires all arguments: format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages
What it means
Thrown by the sandbox's crypto.subtle.unwrapKey wrapper when any of its seven arguments is missing/falsy. unwrapKey has the longest signature in WebCrypto: format, wrappedKey (byte handle), unwrappingKey (CryptoKey handle), unwrapAlgorithm, unwrappedKeyAlgorithm, extractable (=== undefined check), and keyUsages (truthiness, so [] rejected).
Source
Thrown at packages/hoppscotch-js-sandbox/src/cage-modules/crypto.ts:963
const unwrapAlgorithmRaw = ctx.vm.dump(args[3])
const unwrapAlgorithm = normalizeAlgorithm(unwrapAlgorithmRaw)
const unwrappedKeyAlgorithmRaw = ctx.vm.dump(args[4])
const unwrappedKeyAlgorithm = normalizeAlgorithm(
unwrappedKeyAlgorithmRaw
)
const extractable = ctx.vm.dump(args[5]) as boolean
const keyUsages = ctx.vm.dump(args[6]) as KeyUsage[]
if (
!format ||
!wrappedKeyHandle ||
!unwrappingKeyHandle ||
!unwrapAlgorithm ||
!unwrappedKeyAlgorithm ||
extractable === undefined ||
!keyUsages
) {
throw new Error(
"unwrapKey requires all arguments: format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages"
)
}
const wrappedKey = vmArrayToUint8Array(ctx, wrappedKeyHandle)
const unwrappingKey = getKeyFromHandle(unwrappingKeyHandle)
const promiseHandle = ctx.scope.manage(
ctx.vm.newPromise((resolve, reject) => {
trackAsyncOperation(
subtleImpl.unwrapKey(
format,
wrappedKey as BufferSource,
unwrappingKey,
unwrapAlgorithm as AlgorithmIdentifier,
unwrappedKeyAlgorithm as AlgorithmIdentifier,
extractable,
keyUsagesView on GitHub (pinned to 1acb8a3a75)
Solutions
- Pass all seven args in order: format, wrappedKey bytes, unwrappingKey handle, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable boolean, non-empty keyUsages.
- Confirm the wrappedKey is passed as a Uint8Array/byte handle, not a base64 string.
- Ensure the unwrapping key has 'unwrapKey' usage and matches unwrapAlgorithm.
- Provide keyUsages valid for unwrappedKeyAlgorithm (e.g. ['encrypt','decrypt'] for AES-GCM).
Example fix
// before
crypto.subtle.unwrapKey('raw', wrapped, unwrapKey, {name:'AES-GCM',iv})
// after
crypto.subtle.unwrapKey('raw', wrapped, unwrapKey, {name:'AES-GCM',iv}, {name:'AES-GCM',length:256}, true, ['encrypt','decrypt']) Defensive patterns
Strategy: validation
Validate before calling
function safeUnwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgo, unwrappedAlgo, extractable, keyUsages) {
if (!['raw','pkcs8','spki','jwk'].includes(format)) throw new TypeError('unwrapKey: bad format')
if (!wrappedKey || !unwrappingKey) throw new TypeError('unwrapKey: missing key data/handle')
if (!unwrapAlgo?.name || !unwrappedAlgo?.name) throw new TypeError('unwrapKey: both algorithms need a name')
if (typeof extractable !== 'boolean') throw new TypeError('unwrapKey: extractable must be boolean')
if (!Array.isArray(keyUsages) || !keyUsages.length) throw new TypeError('unwrapKey: keyUsages must be non-empty')
return crypto.subtle.unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgo, unwrappedAlgo, extractable, keyUsages)
} Type guard
const isCryptoKeyHandle = (v): boolean => v && typeof v === 'object' && '__keyId' in v
Prevention
- Remember all seven positional args - this is the longest WebCrypto signature.
- Pass wrappedKey as bytes, not a base64 string.
- Give keyUsages valid for unwrappedAlgo.
When it happens
Trigger: Calling unwrapKey with fewer than seven args; omitting either of the two algorithm objects; passing empty keyUsages []; passing wrappedKey as a plain array instead of a VM byte handle; passing extractable positionally wrong.
Common situations: Decrypting a wrapped CEK in a Hoppscotch test and forgetting unwrappedKeyAlgorithm or extractable; mixing up the argument order of the two algorithms.
Related errors
- generateKey requires algorithm, extractable, and keyUsages a
- importKey requires format, keyData, algorithm, extractable,
- exportKey requires format and key arguments
- deriveBits requires algorithm, key, and length arguments
- deriveKey requires algorithm, baseKey, derivedKeyType, extra
AI-assisted analysis of hoppscotch/hoppscotch@1acb8a3a75 (2026-08-12).
Data as JSON: /api/errors/98a7f8472b082df9.
Report an issue: GitHub.