666ghj/MiroFish · warning · ValueError

batch_size must be between 1 and 350

Error message

batch_size must be between 1 and 350

What it means

ValueError from validate_batch_chunks: the batch_size parameter is outside the inclusive range 1..350. 350 is Zep Cloud's documented per-add item limit, and the guard checks it before any Cloud mutation so an invalid grouping cannot produce oversized or empty add requests mid-build.

Source

Thrown at backend/app/services/graph_builder.py:573

                raise RuntimeError(
                    f"Zep batch {batch_id} processing is unconfirmed"
                ) from error

        return BatchSubmission(
            batch_id=batch_id,
            operation_id=operation_id,
            episode_uuids=episode_uuids,
            item_count=total_chunks,
        )

    @staticmethod
    def validate_batch_chunks(chunks: List[str], *, batch_size: int = 350) -> None:
        """Validate every Batch API limit before the first Cloud mutation."""

        if not chunks:
            raise ValueError("At least one text chunk is required")
        if not 1 <= batch_size <= 350:
            raise ValueError("batch_size must be between 1 and 350")
        if len(chunks) > 50_000:
            raise ValueError("A Zep batch cannot contain more than 50,000 items")
        oversized = [index for index, chunk in enumerate(chunks) if len(chunk) > 10_000]
        if oversized:
            raise ValueError(
                f"Zep batch item exceeds 10,000 characters at chunk {oversized[0]}"
            )

    def _list_batch_items(self, batch_id: str) -> List[Any]:
        items: List[Any] = []
        cursor: int | None = None
        seen_cursors: set[int] = set()
        while True:
            page = call_zep_read_with_retry(
                lambda: self.client.batch.list_items(
                    batch_id=batch_id,
                    limit=100,
                    cursor=cursor,

View on GitHub (pinned to b5b53acc57)

Solutions

  1. Set batch_size to a value in 1..350 (350 for fewest requests) wherever the build is invoked.
  2. Trace where the parameter originates (request body, config, UI) and clamp it: batch_size = min(max(1, requested), 350).
  3. If Zep's real limit changed, update the bound in validate_batch_chunks together with the add-loop slicing.
  4. Add request-schema validation at the API layer (e.g. pydantic Field(ge=1, le=350)) so bad values are rejected with a 422 before the service runs.

Example fix

# before
def build_graph_async(self, text, ontology, graph_name=..., chunk_size=500, chunk_overlap=50, batch_size=350):
    ...

# after - clamp at the boundary and enforce in the request model
# api layer
class BuildRequest(BaseModel):
    batch_size: int = Field(default=350, ge=1, le=350)
# service
batch_size = min(max(1, batch_size), 350)
Defensive patterns

Strategy: validation

Validate before calling

batch_size = min(max(1, int(batch_size or 350)), 350)
builder.validate_batch_chunks(chunks, batch_size=batch_size)

Try / catch

try:
    builder.validate_batch_chunks(chunks, batch_size=batch_size)
except ValueError as e:
    if 'batch_size' in str(e):
        batch_size = 350  # sane default, then retry once
        builder.validate_batch_chunks(chunks, batch_size=batch_size)
    else:
        raise

Prevention

When it happens

Trigger: Passing batch_size=0 or a negative number (misconfigured UI field, default of 0 from an unset form value); passing >350 after someone assumed a larger limit; a config change (e.g. env var parsed as 0) flowing into build_graph_async/submit_document_batch.

Common situations: Frontend sends batch_size from an empty input coerced to 0; environment/config typo sets an out-of-range value; code copied from another integration assuming a 500/1000-item limit; Zep raising its limit in a newer API while this service pins 350.

Related errors


AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14). Data as JSON: /api/errors/79ea08c4c111a3db. Report an issue: GitHub.