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
- Pass an explicit, validated integer byte limit (e.g. 10 * 1024 * 1024)
- Use Number.isSafeInteger + non-negative check on any computed limit before calling
- 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
- Never pass Infinity as a limit; choose an explicit integer cap
- Validate size config values at load time with Number.isSafeInteger
- Unit-test limit computation with edge inputs (0, floats, NaN)
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
- Invalid file type
- Either path or blob must be provided
- experimental_subAgent() target must be "claude", "codex", or
- Unsupported upload source
- Invalid Composio CLI release tag: ${releaseTag}
AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28).
Data as JSON: /api/errors/82c90bd483937681.
Report an issue: GitHub.