denoland/deno · error · NodeTypeError

ERR_INVALID_ARG_TYPE

ERR_INVALID_ARG_TYPE

Error message

The "candidate" argument must be ${expected}. Received ${candidate}

What it means

Thrown by checkPrime() in Deno's node:crypto polyfill (ext/node/polyfills/internal/crypto/random.ts:109) when candidate is neither a BigInt nor an ArrayBuffer/TypedArray/Buffer/DataView. The API accepts only binary or BigInt forms; plain numbers, strings, and objects are rejected because primality testing requires arbitrary-precision input.

Source

Thrown at ext/node/polyfills/internal/crypto/random.ts:109

  let candidateBytes: ArrayBufferView | ArrayBuffer;
  if (typeof candidate === "bigint") {
    if (candidate < 0) {
      throw new ERR_OUT_OF_RANGE("candidate", ">= 0", candidate);
    }
    candidateBytes = bigintToBytes(candidate);
  } else if (isAnyArrayBuffer(candidate) || isArrayBufferView(candidate)) {
    const byteLength = isArrayBufferView(candidate)
      ? arrayBufferViewByteLength(candidate as ArrayBufferView)
      : ArrayBufferPrototypeGetByteLength(candidate as ArrayBuffer);
    if (byteLength > OPENSSL_BIGNUM_MAX_BYTES) {
      throw new NodeError(
        "ERR_OSSL_BN_BIGNUM_TOO_LONG",
        "bignum too long",
      );
    }
    candidateBytes = candidate;
  } else {
    throw new ERR_INVALID_ARG_TYPE(
      "candidate",
      [
        "ArrayBuffer",
        "TypedArray",
        "Buffer",
        "DataView",
        "bigint",
      ],
      candidate,
    );
  }

  PromisePrototypeCatch(
    PromisePrototypeThen(
      op_node_check_prime_bytes_async(candidateBytes, checks),
      (result) => {
        callback?.(null, result);
      },

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Convert numbers/strings to BigInt first: BigInt(value) or BigInt('0x' + hexString).
  2. Pass binary data as Buffer/Uint8Array when the value already exists as bytes.
  3. If the value may arrive in several forms, normalize it with a small coercion helper before calling checkPrime.

Example fix

// before
crypto.checkPrime(input /* '0x...f' string */, cb);

// after
const candidate = typeof input === 'string' ? BigInt(input) : input;
crypto.checkPrime(candidate, cb);
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof candidate !== 'bigint' && !ArrayBuffer.isView(candidate) && !(candidate instanceof ArrayBuffer)) throw new TypeError('candidate must be bigint or binary');

Type guard

function isPrimeCandidate(v) { return typeof v === 'bigint' || ArrayBuffer.isView(v) || v instanceof ArrayBuffer; }

Try / catch

try { crypto.checkPrime(c, cb); } catch (e) { if (e.code === 'ERR_INVALID_ARG_TYPE') c = BigInt(c); else throw e; }

Prevention

When it happens

Trigger: crypto.checkPrime(17, cb), crypto.checkPrime('17', cb), or crypto.checkPrime(BigInt('17').toString(), cb). Passing null/undefined or a Number from JSON.parse also triggers it.

Common situations: JSON configuration holding a large number as a string that is passed directly; refactoring code that used a different primality library accepting numbers; forgetting to convert a hex string with BigInt('0x'+hex).

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/42fd1b0f8382ac2f. Report an issue: GitHub.