denoland/deno · error · TypeError

ERR_INVALID_ARG_TYPE

ERR_INVALID_ARG_TYPE

Error message

The "${name}" argument must be of type string or an instance of ArrayBuffer, Buffer, TypedArray, or DataView. Received ${actual}

What it means

The shared getArrayBufferOrView helper normalizes raw crypto material (keys, passwords, salts, passphrases) for many node:crypto APIs. When the value is neither a string, ArrayBuffer, Buffer, TypedArray, nor DataView, it throws ERR_INVALID_ARG_TYPE; the reported argument name varies by call site ('key', 'key.key', 'key.passphrase', 'password', 'salt', 'spkac').

Source

Thrown at ext/node/polyfills/internal/crypto/keys.ts:130

    | Uint32Array => {
    if (isAnyArrayBuffer(buffer)) {
      return new Uint8Array(buffer);
    }
    if (typeof buffer === "string") {
      if (encoding === "buffer") {
        encoding = "utf8";
      }
      return Buffer.from(buffer, encoding);
    }
    if (ObjectPrototypeIsPrototypeOf(DataViewPrototype, buffer)) {
      return new Uint8Array(
        DataViewPrototypeGetBuffer(buffer),
        DataViewPrototypeGetByteOffset(buffer),
        DataViewPrototypeGetByteLength(buffer),
      );
    }
    if (!isArrayBufferView(buffer)) {
      throw new ERR_INVALID_ARG_TYPE(
        name,
        [
          "string",
          "ArrayBuffer",
          "Buffer",
          "TypedArray",
          "DataView",
        ],
        buffer,
      );
    }
    return buffer;
  },
);

const kConsumePublic = 0;
const kConsumePrivate = 1;
const kCreatePublic = 2;

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Convert the value to a Buffer or string before the call: Buffer.from(str), fs.readFileSync(path)
  2. Fix the upstream source of undefined/null (typo'd key name, missing env var, wrong JSON path)
  3. Pass strings or Buffers explicitly; never numbers or plain objects, as crypto material

Example fix

// before
const key = config.apiSecret; // number 98765...
crypto.createSecretKey(key);
// after
const key = Buffer.from(String(config.apiSecret), 'utf8');
crypto.createSecretKey(key);
Defensive patterns

Strategy: type-guard

Validate before calling

function toKeyMaterial(v) {
  if (typeof v === 'string') return Buffer.from(v, 'utf8');
  if (Buffer.isBuffer(v) || v instanceof Uint8Array || v instanceof ArrayBuffer) return v;
  throw new TypeError(`Expected key material, got ${typeof v}`);
}
crypto.createSecretKey(toKeyMaterial(config.secret));

Type guard

function isStringOrBinary(v) {
  return typeof v === 'string' || v instanceof ArrayBuffer || ArrayBuffer.isView(v) || Buffer.isBuffer(v);
}

Try / catch

try {
  crypto.scrypt(password, salt, 64, cb);
} catch (e) {
  if (e.code === 'ERR_INVALID_ARG_TYPE') throw new Error('password/salt must be string or Buffer');
  throw e;
}

Prevention

When it happens

Trigger: crypto.scrypt(12345, 'salt', 64, cb) with a numeric password; crypto.createSecretKey(null); Certificate.exportChallenge(spkac) with a non-buffer; createPublicKey({ key: { key: 42, format: 'pem' } }) where nested key.key is not string/bytes; passing a plain object where key material is expected.

Common situations: Reading key material from JSON/env/config and forgetting to Buffer.from or fs.readFileSync it; undefined caused by typo'd property names in destructuring; assuming numbers or objects are coerced automatically because old scripts did so.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


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