{"record":{"id":"b97060719f7b8623","repo":"khoj-ai/khoj","slug":"those-images-are-way-too-large-for-me-i-can-handl","errorCode":null,"errorMessage":"Those images are way too large for me! I can handle up to {self.max_combined_size_mb}MB of images per message.","messagePattern":"Those images are way too large for me! I can handle up to (.+?)MB of images per message\\.","errorType":"http","errorClass":"HTTPException","httpStatus":429,"severity":"warning","filePath":"src/khoj/routers/helpers.py","lineNumber":2249,"sourceCode":"            )\n\n        # Check total size of images\n        total_size_mb = 0.0\n        for image in body.images:\n            # Unquote the image in case it's URL encoded\n            image = unquote(image)\n            # Assuming the image is a base64 encoded string\n            # Remove the data:image/jpeg;base64, part if present\n            if \",\" in image:\n                image = image.split(\",\", 1)[1]\n\n            # Decode base64 to get the actual size\n            image_bytes = base64.b64decode(image)\n            total_size_mb += len(image_bytes) / (1024 * 1024)  # Convert bytes to MB\n\n        if total_size_mb > self.max_combined_size_mb:\n            logger.info(f\"Data limit: {total_size_mb}MB/{self.max_combined_size_mb}MB size not allowed per message.\")\n            raise HTTPException(\n                status_code=429,\n                detail=f\"Those images are way too large for me! I can handle up to {self.max_combined_size_mb}MB of images per message.\",\n            )\n\n    def check_websocket(self, websocket: WebSocket, body: ChatRequestBody):\n        \"\"\"WebSocket-specific image rate limiting method\"\"\"\n        if state.billing_enabled is False:\n            return\n\n        # Rate limiting is disabled if user unauthenticated.\n        if not websocket.scope.get(\"user\") or not websocket.scope[\"user\"].is_authenticated:\n            return\n\n        if not body.images:\n            return\n\n        # Check number of images\n        if len(body.images) > self.max_images:","sourceCodeStart":2231,"sourceCodeEnd":2267,"githubUrl":"https://github.com/khoj-ai/khoj/blob/ae229ca894c0b80ad84664afcfdde523b5e87057/src/khoj/routers/helpers.py#L2231-L2267","documentation":"A 429 raised when the total decoded size of all base64 images in one chat message exceeds `max_combined_size_mb` MB. Each image is base64-decoded server-side and the summed byte sizes compared against the cap.","triggerScenarios":"Sending a message whose images, after base64 decoding, sum to more than `self.max_combined_size_mb` megabytes (e.g. several high-res phone photos in one request).","commonSituations":"Modern phone photos (3-8MB each) easily exceeding a small combined cap; clients sending originals without compression; forgetting that base64 inflates payloads ~33% and that the limit applies to decoded bytes.","solutions":["Compress/resize images client-side (e.g. re-encode as JPEG at reduced quality/dimensions) before sending","Send large images across multiple messages under the per-message cap","Check the deployment's max_combined_size_mb configuration","Remove duplicate or unnecessary images from the payload"],"exampleFix":"// before\nconst images = await Promise.all(files.map(f => fileToBase64(f)))\n// after\nconst images = await Promise.all(files.map(f => compressToUnder(f, 1_000_000)))  // ~1MB each","handlingStrategy":"validation","validationCode":"import base64\nMAX_MB = 10\ntotal = sum(len(base64.b64decode(img or '')) for img in body.images) / (1024*1024)\nif total > MAX_MB:\n    images = compress_until_under(body.images, MAX_MB)","typeGuard":"def under_size_cap(images: list[str] | None, cap_mb: float) -> bool:\n    if not images:\n        return True\n    total = sum(len(base64.b64decode(i)) for i in images)\n    return total <= cap_mb * 1024 * 1024","tryCatchPattern":"try:\n    resp = await client.post('/api/chat', json=body)\nexcept HTTPStatusError as e:\n    if e.response.status_code == 429 and 'too large' in e.response.text:\n        body['images'] = await recompress(body['images'])\n        resp = await client.post('/api/chat', json=body)\n    else:\n        raise","preventionTips":["Compress/resize images client-side before base64 encoding","Split large sets across multiple messages","Remember the cap applies to decoded bytes, not the base64 string length"],"tags":["rate-limit","http-429","images","payload-size","base64"],"backgroundTag":"request-payload-limit-exceeded","analyzedSha":"ae229ca894c0b80ad84664afcfdde523b5e87057","analyzedAt":"2026-08-27T03:32:41.843Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}