{"record":{"id":"79ea08c4c111a3db","repo":"666ghj/MiroFish","slug":"batch-size-must-be-between-1-and-350","errorCode":null,"errorMessage":"batch_size must be between 1 and 350","messagePattern":"batch_size must be between 1 and 350","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"backend/app/services/graph_builder.py","lineNumber":573,"sourceCode":"                raise RuntimeError(\n                    f\"Zep batch {batch_id} processing is unconfirmed\"\n                ) from error\n\n        return BatchSubmission(\n            batch_id=batch_id,\n            operation_id=operation_id,\n            episode_uuids=episode_uuids,\n            item_count=total_chunks,\n        )\n\n    @staticmethod\n    def validate_batch_chunks(chunks: List[str], *, batch_size: int = 350) -> None:\n        \"\"\"Validate every Batch API limit before the first Cloud mutation.\"\"\"\n\n        if not chunks:\n            raise ValueError(\"At least one text chunk is required\")\n        if not 1 <= batch_size <= 350:\n            raise ValueError(\"batch_size must be between 1 and 350\")\n        if len(chunks) > 50_000:\n            raise ValueError(\"A Zep batch cannot contain more than 50,000 items\")\n        oversized = [index for index, chunk in enumerate(chunks) if len(chunk) > 10_000]\n        if oversized:\n            raise ValueError(\n                f\"Zep batch item exceeds 10,000 characters at chunk {oversized[0]}\"\n            )\n\n    def _list_batch_items(self, batch_id: str) -> List[Any]:\n        items: List[Any] = []\n        cursor: int | None = None\n        seen_cursors: set[int] = set()\n        while True:\n            page = call_zep_read_with_retry(\n                lambda: self.client.batch.list_items(\n                    batch_id=batch_id,\n                    limit=100,\n                    cursor=cursor,","sourceCodeStart":555,"sourceCodeEnd":591,"githubUrl":"https://github.com/666ghj/MiroFish/blob/b5b53acc57189a4a42e44a23e149dc655c98fe82/backend/app/services/graph_builder.py#L555-L591","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set batch_size to a value in 1..350 (350 for fewest requests) wherever the build is invoked.","Trace where the parameter originates (request body, config, UI) and clamp it: batch_size = min(max(1, requested), 350).","If Zep's real limit changed, update the bound in validate_batch_chunks together with the add-loop slicing.","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."],"exampleFix":"# before\ndef build_graph_async(self, text, ontology, graph_name=..., chunk_size=500, chunk_overlap=50, batch_size=350):\n    ...\n\n# after - clamp at the boundary and enforce in the request model\n# api layer\nclass BuildRequest(BaseModel):\n    batch_size: int = Field(default=350, ge=1, le=350)\n# service\nbatch_size = min(max(1, batch_size), 350)","handlingStrategy":"validation","validationCode":"batch_size = min(max(1, int(batch_size or 350)), 350)\nbuilder.validate_batch_chunks(chunks, batch_size=batch_size)","typeGuard":null,"tryCatchPattern":"try:\n    builder.validate_batch_chunks(chunks, batch_size=batch_size)\nexcept ValueError as e:\n    if 'batch_size' in str(e):\n        batch_size = 350  # sane default, then retry once\n        builder.validate_batch_chunks(chunks, batch_size=batch_size)\n    else:\n        raise","preventionTips":["Declare batch_size with schema bounds at the request layer (pydantic Field(ge=1, le=350)).","Clamp client-supplied values instead of trusting them: min(max(1, v), 350).","Treat 0-valued config from empty form fields as 'unset' and substitute the default.","Update the bound in lockstep with the Zep API version in use."],"tags":["backend","python","zep","validation","parameter-range"],"backgroundTag":null,"analyzedSha":"b5b53acc57189a4a42e44a23e149dc655c98fe82","analyzedAt":"2026-08-14T22:29:33.146Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}