{"record":{"id":"1bd2c656dc76b572","repo":"denoland/deno","slug":"err-invalid-arg-type-1bd2c6","errorCode":"ERR_INVALID_ARG_TYPE","errorMessage":"The \"${name}\" argument must be an instance of Buffer, ArrayBuffer, TypedArray, or DataView","messagePattern":"The \"(.+?)\" argument must be an instance of Buffer, ArrayBuffer, TypedArray, or DataView","errorType":"error_code","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal_binding/_timingSafeEqual.ts","lineNumber":35,"sourceCode":"  ArrayBufferIsView,\n  ArrayBufferPrototypeGetByteLength,\n  DataView,\n  DataViewPrototypeGetBuffer,\n  DataViewPrototypeGetByteLength,\n  DataViewPrototypeGetByteOffset,\n  DataViewPrototypeGetUint8,\n  ObjectPrototypeIsPrototypeOf,\n  TypedArrayPrototypeGetBuffer,\n  TypedArrayPrototypeGetByteLength,\n  TypedArrayPrototypeGetByteOffset,\n} = primordials;\n\nfunction validateBuffer(\n  buf: unknown,\n  name: string,\n): asserts buf is ArrayBufferLike | ArrayBufferView {\n  if (!isAnyArrayBuffer(buf) && !isArrayBufferView(buf)) {\n    throw new ERR_INVALID_ARG_TYPE(\n      name,\n      [\"Buffer\", \"ArrayBuffer\", \"TypedArray\", \"DataView\"],\n      buf,\n    );\n  }\n}\n\nfunction byteLengthOf(\n  ab: ArrayBufferView | ArrayBufferLike | DataView,\n): number {\n  if (isDataView(ab)) {\n    return DataViewPrototypeGetByteLength(ab);\n  }\n  if (ArrayBufferIsView(ab)) {\n    return TypedArrayPrototypeGetByteLength(ab);\n  }\n  return ArrayBufferPrototypeGetByteLength(ab);\n}","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal_binding/_timingSafeEqual.ts#L17-L53","documentation":"Deno's internal crypto.timingSafeEqual binding only accepts Buffer, ArrayBuffer/SharedArrayBuffer, TypedArray, or DataView inputs — validated by validateBuffer in ext/node/polyfills/internal_binding/_timingSafeEqual.ts. Strings, numbers, and wrapper objects throw ERR_INVALID_ARG_TYPE listing the accepted types. (The public node:crypto API in Node itself only accepts Buffers; Deno's binding is deliberately broader.)","triggerScenarios":"crypto.timingSafeEqual(token, storedToken) where both are hex/base64 strings; one side a Buffer and the other a base64url string; passing { data } wrapper objects or numbers; comparing JWT signature strings without decoding.","commonSituations":"Auth code comparing user-supplied tokens, API keys, HMAC digests, or webhooks signatures still in their encoded string form; data crossing a JSON boundary so buffers arrive as strings.","solutions":["Decode both sides to Buffers with matching encodings: Buffer.from(a, 'hex') and Buffer.from(b, 'hex')","If either input may be a string, normalize first: const toBuf = (v) => Buffer.isBuffer(v) ? v : Buffer.from(String(v), 'hex')","Do not pass substrings of encoded values with prefixes (e.g. 'Bearer ') — strip first, then decode"],"exampleFix":"// before\ncrypto.timingSafeEqual(req.header('x-signature'), computedHex); // strings -> throws\n\n// after\ncrypto.timingSafeEqual(\n  Buffer.from(req.header('x-signature'), 'hex'),\n  Buffer.from(computedHex, 'hex'),\n);","handlingStrategy":"type-guard","validationCode":"const toBuf = (v: unknown) =>\n  Buffer.isBuffer(v) ? v\n  : v instanceof ArrayBuffer || ArrayBuffer.isView(v) ? Buffer.from(v as any)\n  : Buffer.from(String(v), 'hex');\nif (!Buffer.isBuffer(a) && !ArrayBuffer.isView(a) && !(a instanceof ArrayBuffer)) {\n  throw new TypeError('timingSafeEqual inputs must be buffer-like');\n}\ncrypto.timingSafeEqual(toBuf(a), toBuf(b));","typeGuard":"function isBufferLike(v: unknown): v is Buffer | ArrayBufferView | ArrayBuffer {\n  return Buffer.isBuffer(v) || ArrayBuffer.isView(v) || v instanceof ArrayBuffer;\n}","tryCatchPattern":"try {\n  ok = crypto.timingSafeEqual(a, b);\n} catch (e: any) {\n  if (e?.code === 'ERR_INVALID_ARG_TYPE') {\n    ok = crypto.timingSafeEqual(toBuf(a), toBuf(b));\n  } else throw e;\n}","preventionTips":["Decode string tokens/mac signatures to Buffers at the API boundary, not at compare time","Keep a single toBuf normalizer for security-comparison code paths","Type the compare helper's parameters as (a: Buffer, b: Buffer) so TS rejects strings"],"tags":["crypto","security","node-compat","argument-validation"],"backgroundTag":"invalid-argument-type","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-21T08:17:14.275Z"}