crewAIInc/crewAI · error · ValueError

max_bytes must be positive, got {max_bytes}.

Error message

max_bytes must be positive, got {max_bytes}.

What it means

Pure argument-validation error from fetch_url_body() in safe_requests.py: max_bytes must be a positive integer, and the function raises immediately (before any network I/O) when max_bytes <= 0. The limit exists so streamed bodies are capped; zero or negative caps are meaningless and rejected rather than silently disabling the cap.

Source

Thrown at lib/crewai-tools/src/crewai_tools/security/safe_requests.py:136

    Args:
        url: The URL to fetch.
        max_bytes: Largest body to accept, in decoded bytes.
        timeout: Request timeout, passed through to requests.
        headers: Request headers.
        max_redirects: Hops to follow before giving up.

    Returns:
        A ``(body, content_type, final_url)`` tuple, where *final_url* is the
        last validated URL in the redirect chain.

    Raises:
        ValueError: If *max_bytes* is not positive, URL validation fails, the
            redirect chain is too long, or the body exceeds *max_bytes*.
        requests.RequestException: If the request fails or returns an error
            status.
    """
    if max_bytes <= 0:
        raise ValueError(f"max_bytes must be positive, got {max_bytes}.")

    response = safe_get(
        url,
        max_redirects=max_redirects,
        headers=headers,
        timeout=timeout,
        stream=True,
    )
    try:
        response.raise_for_status()

        chunks: list[bytes] = []
        total = 0
        for chunk in response.iter_content(chunk_size=_STREAM_CHUNK_SIZE):
            if not chunk:
                continue
            total += len(chunk)
            if total > max_bytes:

View on GitHub (pinned to 754d7323be)

Solutions

  1. Pass an explicit positive byte limit, e.g. max_bytes=5_000_000 for ~5 MB.
  2. If you intended 'unlimited', pick a large-but-finite sentinel (e.g. 1 GB) — the parameter is intentionally mandatory-positive.
  3. Fix the upstream computation so it cannot produce <= 0 (clamp with max(1, value)).

Example fix

# before
body, ctype, url = fetch_url_body(url, max_bytes=0)  # means 'unlimited' to caller

# after
body, ctype, url = fetch_url_body(url, max_bytes=1_000_000_000)
Defensive patterns

Strategy: validation

Validate before calling

max_bytes = max(1, int(max_bytes))  # clamp before calling
assert max_bytes > 0

Type guard

def is_positive_int(v) -> bool:
    return isinstance(v, int) and not isinstance(v, bool) and v > 0

Prevention

When it happens

Trigger: Calling fetch_url_body(url, max_bytes=0) hoping to mean 'unlimited'; passing a computed size that underflows to 0/negative (e.g. subtracting an offset larger than the base); a config default of 0 flowing into the parameter.

Common situations: Config files where the byte limit is left at 0 meaning 'not set'; arithmetic on chunk budgets; new callers assuming 0 disables the check.

Related errors


AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15). Data as JSON: /api/errors/7e2956d4b5afe652. Report an issue: GitHub.