usebruno/bruno · error · RangeError
The "size" argument must be >= 0
Error message
The "size" argument must be >= 0
What it means
Thrown by the QuickJS sandbox crypto shim for crypto.randomBytes when `size` is a number but negative. Equivalent to Node.js's ERR_OUT_OF_RANGE check. The shim truncates to an integer first (Math.trunc) before the comparison, so -0.5 also trips it.
Source
Thrown at packages/bruno-js/src/sandbox/quickjs/shims/lib/crypto-utils.js:21
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);
const byteArray = Array.from(buffer);
return marshallToVm(byteArray, vm);
} catch (error) {
const vmError = vm.newError(error.message);
vm.setProp(vmError, 'name', vm.newString(error.name));View on GitHub (pinned to 9bdd81c7bd)
Solutions
- Clamp to zero minimum: `crypto.randomBytes(Math.max(0, size))`.
- Debug where the negative value originates — log size before the call.
- Validate upstream: if size < 0, return early or throw a clearer domain error.
Example fix
// before
const n = end - start; // can be negative
const b = crypto.randomBytes(n);
// after
if (end < start) throw new Error('end must be >= start');
const b = crypto.randomBytes(end - start); Defensive patterns
Strategy: validation
Validate before calling
function safeRandomBytes(size) {
const n = Math.trunc(Number(size));
if (!(n >= 0)) throw new RangeError('size must be >= 0');
return crypto.randomBytes(n);
} Type guard
const isNonNegativeInt = (v) => Number.isInteger(v) && v >= 0;
Try / catch
try { crypto.randomBytes(n); }
catch (err) {
if (/must be >= 0/.test(err.message)) { crypto.randomBytes(Math.max(0, n)); }
else throw err;
} Prevention
- Clamp computed lengths with Math.max(0, x).
- Validate upstream arithmetic that produces buffer lengths.
When it happens
Trigger: Passing a negative length to crypto.randomBytes inside a QuickJS-sandboxed script — e.g. size derived from a subtraction that underflows, or a loop bound computed from a missing/zero field.
Common situations: Buffer length computed as `a - b` where b > a; off-by-one in slicing that yields a negative count; reading a length from a response where the field is absent and defaults to -1.
Related errors
- The "size" argument is too large
- The "size" argument must be of type number
- getRandomValues: ArrayBufferView byte length exceeds 65536
- getRandomValues: Invalid typed array object
- getRandomValues: Invalid or unsupported typed array type: ${
AI-assisted analysis of usebruno/bruno@9bdd81c7bd (2026-08-13).
Data as JSON: /api/errors/10d1fa6105353d06.
Report an issue: GitHub.