denoland/deno · error · RangeError

ERR_OUT_OF_RANGE

ERR_OUT_OF_RANGE

Error message

The value of "options.maxBuffer" is out of range. It must be a positive number. Received ${received}

What it means

execFile merges user options over defaults (maxBuffer: 1 MiB, timeout: 0) and validates them before spawning. A maxBuffer below zero is rejected with ERR_OUT_OF_RANGE because a buffer cap cannot be negative; the 'positive number' wording mirrors Node's message. Note the check is strictly `maxBuffer < 0` — zero and NaN pass this particular guard (NaN fails comparisons).

Source

Thrown at ext/node/polyfills/child_process.ts:585

    }
    // Validate callback if provided
    if (maybeCallback != null && typeof maybeCallback !== "function") {
      throw new ERR_INVALID_ARG_TYPE("callback", "function", maybeCallback);
    }
  }

  const execOptions = {
    __proto__: null,
    encoding: "utf8",
    timeout: 0,
    maxBuffer: MAX_BUFFER,
    killSignal: "SIGTERM",
    shell: false,
    ...options,
  };
  validateTimeout(execOptions.timeout);
  if (execOptions.maxBuffer < 0) {
    throw new ERR_OUT_OF_RANGE(
      "options.maxBuffer",
      "a positive number",
      execOptions.maxBuffer,
    );
  }
  const spawnOptions: SpawnOptions = {
    argv0: execOptions.argv0,
    cwd: execOptions.cwd,
    env: execOptions.env,
    gid: execOptions.gid,
    shell: execOptions.shell,
    signal: execOptions.signal,
    uid: execOptions.uid,
    windowsHide: execOptions.windowsHide !== false,
    windowsVerbatimArguments: !!execOptions.windowsVerbatimArguments,
  };

  const child = spawn(file, args, spawnOptions);

View on GitHub (pinned to 89f33cbef2)

Solutions

  1. Use a non-negative number; omit maxBuffer to get the 1 MiB default
  2. Clamp computed values: maxBuffer: Math.max(0, n)
  3. For big outputs pass a large finite value (e.g. 1024 * 1024 * 100) instead of any negative sentinel

Example fix

// before
execFile("ls", ["-la"], { maxBuffer: quota - used }, cb);
// after
execFile("ls", ["-la"], { maxBuffer: Math.max(0, quota - used) }, cb);
Defensive patterns

Strategy: validation

Validate before calling

const maxBuffer = Number(opts.maxBuffer ?? 1024 * 1024);
if (!Number.isFinite(maxBuffer) || maxBuffer < 0) {
  throw new RangeError("options.maxBuffer must be a finite number >= 0");
}
opts = { ...opts, maxBuffer: Math.max(0, maxBuffer) };

Type guard

const isValidMaxBuffer = (n) => n == null || (Number.isFinite(n) && n >= 0);

Try / catch

try { execFile(file, args, opts, cb); }
catch (e) {
  if (e.code === "ERR_OUT_OF_RANGE" && e.message.includes("maxBuffer")) {
    execFile(file, args, { ...opts, maxBuffer: 1024 * 1024 }, cb);
  } else throw e;
}

Prevention

When it happens

Trigger: execFile('ls', ['-la'], { maxBuffer: -1 }); { maxBuffer: -Infinity }; computed sizes like maxBuffer: quota - used where the subtraction goes negative.

Common situations: Sizing buffers from remaining-memory or quota calculations; porting scripts that used negative numbers to mean 'unlimited'; sign typos in config-driven values. timeout is validated first (validateTimeout), so a bad timeout throws its own error before this one.

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/9828552520005da5. Report an issue: GitHub.