rohitg00/ai-engineering-from-scratch · error · ValueError

batch size must be positive

Error message

batch size must be positive

What it means

Raised by batch() when size is less than 1. The function slices items into fixed-size chunks via range(0, len(items), size); zero or negative sizes would silently produce wrong or empty results, so it fails fast instead (test_batch_and_cache_helpers_are_deterministic).

Source

Thrown at certifications/claude/lessons/08-messages-api-and-application-lifecycle/code/main.py:180

    stopped = False
    for event in events:
        event_type = event.get("type")
        if stopped:
            raise ProtocolError("event arrived after message_stop")
        if event_type == "content_block_delta":
            delta = event.get("delta", {})
            if delta.get("type") == "text_delta":
                chunks.append(str(delta.get("text", "")))
        elif event_type == "message_stop":
            stopped = True
    if not stopped:
        raise ProtocolError("stream ended without message_stop")
    return "".join(chunks)


def batch(items: list[Any], size: int) -> list[list[Any]]:
    if size < 1:
        raise ValueError("batch size must be positive")
    return [items[index : index + size] for index in range(0, len(items), size)]


def stable_cache_key(model: str, stable_prefix: str) -> str:
    payload = f"{model}\0{stable_prefix}".encode("utf-8")
    return hashlib.sha256(payload).hexdigest()


IMAGE_MEDIA_TYPES = {"image/jpeg", "image/png", "image/gif", "image/webp"}
DOCUMENT_MEDIA_TYPES = {"application/pdf", "text/plain"}


def build_multimodal_request(prompt: str, image_bytes: bytes, reusable_file_id: str) -> dict[str, Any]:
    """Build an offline request body with inline vision and a reusable file asset."""
    if not prompt.strip():
        raise ValueError("prompt must not be empty")
    if not image_bytes:
        raise ValueError("image_bytes must not be empty")

View on GitHub (pinned to 39ea8a1c6d)

Solutions

  1. Pass a positive integer size (typically 1-100)
  2. Validate configurable batch sizes at startup and clamp or fail before the loop
  3. Add a check where the size is computed, not where batch is called

Example fix

# before
size = total // count  # 0 when total < count
batch(items, size)
# after
size = max(1, total // count)
batch(items, size)
Defensive patterns

Strategy: validation

Validate before calling

if not isinstance(size, int) or size < 1:
    raise ValueError("batch size must be a positive integer")
result = batch(items, size)

Prevention

When it happens

Trigger: Calling batch(items, 0), batch(items, -2), or passing a size computed from config/env that evaluates to 0.

Common situations: Batch size read from an env var or CLI flag that defaults to 0, integer division producing 0 for small inputs, or a size variable left uninitialized.

Related errors


AI-assisted analysis of rohitg00/ai-engineering-from-scratch@39ea8a1c6d (2026-08-26). Data as JSON: /api/errors/adf75e45b58252c7. Report an issue: GitHub.