ComposioHQ/composio · error · RangeError

maxBytes must be a non-negative safe integer

Error message

maxBytes must be a non-negative safe integer

What it means

readResponseBodyWithLimit reads a fetch body with a byte cap (default 100 MiB for URL uploads). It validates its maxBytes argument and throws a RangeError when it is negative, fractional, NaN, Infinity, or beyond the safe-integer range.

Source

Thrown at ts/packages/core/src/utils/readResponseBody.ts:18

/** Maximum size accepted for files fetched from user-supplied URLs (100 MiB). */
export const MAX_URL_UPLOAD_SIZE_BYTES = 100 * 1024 * 1024;

const sizeLimitError = (actualSize: number, maxBytes: number): Error =>
  new Error(`File size (${actualSize} bytes) exceeds maximum allowed size (${maxBytes} bytes)`);

/**
 * Read a fetch response without allowing an untrusted server to exhaust memory.
 *
 * `Content-Length` is checked as an early rejection, but the streamed byte
 * count is authoritative because the header can be absent or dishonest.
 */
export const readResponseBodyWithLimit = async (
  response: Response,
  maxBytes: number = MAX_URL_UPLOAD_SIZE_BYTES
): Promise<Uint8Array> => {
  if (!Number.isSafeInteger(maxBytes) || maxBytes < 0) {
    throw new RangeError('maxBytes must be a non-negative safe integer');
  }

  const contentLength = response.headers.get('content-length')?.trim();
  if (contentLength && /^\d+$/.test(contentLength)) {
    const declaredSize = Number(contentLength);
    if (!Number.isSafeInteger(declaredSize) || declaredSize > maxBytes) {
      const error = sizeLimitError(declaredSize, maxBytes);
      await response.body?.cancel(error).catch(() => undefined);
      throw error;
    }
  }

  if (!response.body) {
    return new Uint8Array();
  }

  const reader = response.body.getReader();
  const chunks: Uint8Array[] = [];

View on GitHub (pinned to 64b1b85502)

Solutions

  1. Pass an explicit, validated integer byte limit (e.g. 10 * 1024 * 1024)
  2. Use Number.isSafeInteger + non-negative check on any computed limit before calling
  3. For 'unlimited', pass a large safe integer instead of Infinity

Example fix

// before
await readResponseBodyWithLimit(res, Infinity);

// after
const MAX = 100 * 1024 * 1024; // explicit cap
await readResponseBodyWithLimit(res, MAX);
Defensive patterns

Strategy: validation

Validate before calling

if (!Number.isSafeInteger(maxBytes) || maxBytes < 0) {
  throw new Error(`Bad maxBytes: ${maxBytes}`);
}

Type guard

const isValidLimit = (n: unknown): n is number =>
  typeof n === 'number' && Number.isSafeInteger(n) && n >= 0;

Try / catch

try {
  await readResponseBodyWithLimit(res, limit);
} catch (e) {
  if (e instanceof RangeError) {
    // fix the limit computation, don't retry
  }
}

Prevention

When it happens

Trigger: Calling readResponseBodyWithLimit(response, maxBytes) with a computed/derived limit that is negative, a float (e.g. 1.5 * 1024 * 1024), NaN, or Infinity — commonly from a config value parsed incorrectly or a default like Number.MAX_VALUE.

Common situations: Passing Infinity intending 'no limit'; parsing a size string like '10MB' into NaN; a subtraction underflowing to a negative number; passing a value from unvalidated user input.

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 ComposioHQ/composio@64b1b85502 (2026-08-28). Data as JSON: /api/errors/82c90bd483937681. Report an issue: GitHub.