{"record":{"id":"20675ade4ea232b2","repo":"calesthio/OpenMontage","slug":"ark-request-body-must-be-smaller-than-64-mb","errorCode":null,"errorMessage":"Ark request body must be smaller than 64 MB","messagePattern":"Ark request body must be smaller than 64 MB","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/video/seedance_ark.py","lineNumber":1236,"sourceCode":"        if safety is not None and len(str(safety)) > 64:\n            raise ValueError(\"safety_identifier must be at most 64 characters\")\n\n    def _validate_request_size(self, payload: dict[str, Any]) -> None:\n        # Base64 dominates request size; summing encoded media is a conservative\n        # lower-cost check that avoids building a second complete JSON string.\n        encoded_bytes = 0\n        for item in payload[\"content\"]:\n            media = (\n                item.get(\"image_url\")\n                or item.get(\"audio_url\")\n                or item.get(\"video_url\")\n                or {}\n            )\n            url = str(media.get(\"url\", \"\"))\n            if url.startswith(\"data:\"):\n                encoded_bytes += len(url.encode(\"ascii\"))\n        if encoded_bytes >= self.MAX_REQUEST_BYTES:\n            raise ValueError(\"Ark request body must be smaller than 64 MB\")\n\n    @staticmethod\n    def _media_counts(content: list[dict[str, Any]]) -> dict[str, int]:\n        return {\n            kind: sum(1 for item in content if item.get(\"type\") == kind)\n            for kind in (\"text\", \"image_url\", \"video_url\", \"audio_url\")\n        }\n\n    def _headers(self, api_key: str) -> dict[str, str]:\n        return {\n            \"Authorization\": f\"Bearer {api_key}\",\n            \"Content-Type\": \"application/json\",\n        }\n\n    def _create_task(self, payload: dict[str, Any], api_key: str) -> str:\n        import requests\n\n        response = requests.post(","sourceCodeStart":1218,"sourceCodeEnd":1254,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/tools/video/seedance_ark.py#L1218-L1254","documentation":"Raised by SeedanceArkVideo._validate_request_size when the summed size of base64 data: URLs inside payload['content'] reaches MAX_REQUEST_BYTES (64 MB). Ark rejects oversized request bodies at the HTTP layer, so the client pre-computes the dominant cost — the encoded media — and fails fast instead of uploading 64+ MB only to get a 413.","triggerScenarios":"Passing inline base64 images/audio/video (data: URLs) in content items whose combined encoded length reaches 64 MB — e.g. one 50 MB base64 video plus a 20 MB base64 image, or several ~10 MB images in a multi-reference request.","commonSituations":"Using local files converted to data URLs instead of uploading them to object storage and passing https URLs; high-resolution reference images from phones or stock libraries; batches that worked individually but are combined into one reference-conditioned generation.","solutions":["Upload media to accessible storage (S3, OSS, any https URL Ark can fetch) and pass URLs instead of data: URLs.","Reduce media resolution/bitrate or trim audio/video clips before base64-encoding.","Split the request: generate with fewer references per call instead of one mega-payload.","If local-only operation is required, ensure combined base64 payload stays well under 64 MB (remember base64 adds ~33% over raw bytes)."],"exampleFix":"# before\ncontent.append({\"type\": \"image_url\", \"image_url\": {\"url\": f\"data:image/png;base64,{b64}\"}})\n\n# after\ncontent.append({\"type\": \"image_url\", \"image_url\": {\"url\": uploaded_https_url}})","handlingStrategy":"validation","validationCode":"MAX = 64 * 1024 * 1024\ntotal = sum(len(str((it.get(\"image_url\") or it.get(\"audio_url\") or it.get(\"video_url\") or {}).get(\"url\", \"\"))) for it in content if str((it.get(\"image_url\") or it.get(\"audio_url\") or it.get(\"video_url\") or {}).get(\"url\", \"\")).startswith(\"data:\"))\nif total >= MAX:\n    content = [replace_data_urls_with_https(it) for it in content]  # upload media first","typeGuard":null,"tryCatchPattern":"try:\n    result = tool.run(inputs)\nexcept ValueError as e:\n    if \"64 MB\" in str(e):\n        inputs = upload_media_and_swap_to_https(inputs)\n        result = tool.run(inputs)\n    else:\n        raise","preventionTips":["Prefer hosted https URLs over data: URLs for any media over ~1 MB.","Remember base64 inflates payloads ~33% over raw file size when budgeting."],"tags":["validation","seedance","ark","payload-size","base64"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}