usebruno/bruno · error · TypeError

The "size" argument must be of type number

Error message

The "size" argument must be of type number

What it means

Thrown by the QuickJS sandbox crypto shim for crypto.randomBytes when the `size` argument passed from sandbox code is not a JavaScript number (e.g. a string, undefined, null, boolean, object). It mirrors Node.js's built-in ERR_INVALID_ARG_TYPE check for the same API.

Source

Thrown at packages/bruno-js/src/sandbox/quickjs/shims/lib/crypto-utils.js:15

const crypto = require('node:crypto');
const { marshallToVm } = require('../../utils');
const { serializeTypedArray, deserializeTypedArray } = require('./utils');

/**
 * Node.js crypto module shim for QuickJS sandbox
 * Implements crypto.randomBytes and crypto.getRandomValues functions
 */
const addCryptoUtilsShimToContext = async (vm) => {
  let randomBytesHandle = vm.newFunction('randomBytes', function (sizeHandle) {
    try {
      let size = vm.dump(sizeHandle);

      if (typeof size !== 'number') {
        throw new TypeError('The "size" argument must be of type number');
      }

      size = Math.trunc(size);

      if (size < 0) {
        throw new RangeError('The "size" argument must be >= 0');
      }

      if (size > 65536) { // 2^31 - 1 (max safe integer for practical use)
        throw new RangeError('The "size" argument is too large');
      }

      if (size === 0) {
        return marshallToVm([], vm);
      }

      const buffer = crypto.randomBytes(size);

View on GitHub (pinned to 9bdd81c7bd)

Solutions

  1. Coerce the argument explicitly: `crypto.randomBytes(Number(size))` or `crypto.randomBytes(parseInt(size, 10))`.
  2. Guard against undefined/null before calling: `if (size == null) throw ...`.
  3. If the value comes from a Bruno variable, convert it once when reading: `const size = Number(bru.getVar('tokenSize'))`.

Example fix

// before
const bytes = crypto.randomBytes(bru.getVar('size')); // var is a string

// after
const bytes = crypto.randomBytes(Number(bru.getVar('size')));
Defensive patterns

Strategy: validation

Validate before calling

function safeRandomBytes(size) {
  if (typeof size !== 'number' || Number.isNaN(size)) {
    throw new TypeError('size must be a number');
  }
  return crypto.randomBytes(size);
}

Type guard

const isNumber = (v) => typeof v === 'number' && !Number.isNaN(v);

Try / catch

try {
  const b = crypto.randomBytes(maybeString);
} catch (err) {
  if (/must be of type number/.test(err.message)) {
    const b = crypto.randomBytes(Number(maybeString));
  } else throw err;
}

Prevention

When it happens

Trigger: Calling crypto.randomBytes(undefined), crypto.randomBytes('16'), crypto.randomBytes(null), or passing a variable that was never assigned a numeric value inside a QuickJS-sandboxed Bru script.

Common situations: Size comes from bru.getVar() (returns a string) and is fed straight to randomBytes; an optional function parameter defaults to undefined; parseInt/Number coercion was forgotten before the call.

Related errors


AI-assisted analysis of usebruno/bruno@9bdd81c7bd (2026-08-13). Data as JSON: /api/errors/ced24167fe27c792. Report an issue: GitHub.