{"record":{"id":"a6264061f07c3b88","repo":"calesthio/OpenMontage","slug":"no-poster-frame-available","errorCode":null,"errorMessage":"no poster frame available","messagePattern":"no poster frame available","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"backlot/server.py","lineNumber":260,"sourceCode":"    # ---- Thumbnails (downscaled, cached on disk) ------------------------\n\n    @app.get(\"/thumb/{project_id}/{file_path:path}\")\n    async def thumb(project_id: str, file_path: str, w: int = 640) -> FileResponse:\n        project_dir = _safe_project_dir(project_id)\n        target = (project_dir / file_path).resolve()\n        try:\n            target.relative_to(project_dir.resolve())\n        except ValueError:\n            raise HTTPException(status_code=403, detail=\"path escapes project\")\n        if not target.is_file():\n            raise HTTPException(status_code=404, detail=\"media not found\")\n        width = min(THUMB_WIDTHS, key=lambda x: abs(x - w))\n        cached = await asyncio.to_thread(_thumbnail_for, target, width)\n        if cached is None:\n            # Never fall back to raw video bytes for an <img> consumer (F-03);\n            # non-thumbable images are safe to serve as-is.\n            if target.suffix.lower() in {\".mp4\", \".webm\", \".mov\"}:\n                raise HTTPException(status_code=404, detail=\"no poster frame available\")\n            return FileResponse(target)\n        return FileResponse(cached, media_type=\"image/jpeg\")\n\n    # ---- Media (range requests handled by FileResponse) ---------------\n\n    @app.get(\"/media/{project_id}/{file_path:path}\")\n    async def media(project_id: str, file_path: str) -> FileResponse:\n        project_dir = _safe_project_dir(project_id)\n        target = (project_dir / file_path).resolve()\n        try:\n            target.relative_to(project_dir.resolve())\n        except ValueError:\n            raise HTTPException(status_code=403, detail=\"path escapes project\")\n        if not target.is_file():\n            raise HTTPException(status_code=404, detail=\"media not found\")\n        return FileResponse(target)\n\n    # ---- UI ------------------------------------------------------------","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/backlot/server.py#L242-L278","documentation":"A local reference file was found but its byte size is >= max_bytes, so the tool refuses to base64-encode and inline it into the Ark request. The limit is expressed in MB in the message (max_bytes // 1024 // 1024) and exists to keep the request payload within Ark's size limits.","triggerScenarios":"Attaching a high-resolution PNG photo (e.g. 30 MB) or WAV audio as a local reference when the configured cap (typically a few MB) is exceeded.","commonSituations":"Raw camera scans or uncompressed audio used as references; re-using a previously downloaded master asset without compressing; different providers having different caps so an asset accepted elsewhere is rejected here.","solutions":["Compress/resize the image (e.g. convert to JPEG quality ~85, longest side under 6000px — also required by the dimension check).","Re-encode audio to a compact AAC/MP3 at moderate bitrate.","Alternatively host the file at a public https URL and pass that instead of a local path, which bypasses local size inlining."],"exampleFix":"# before\ninputs = {\"reference_image_path\": \"raw_scan.png\"}  # 40MB\n# after\nfrom PIL import Image\nimg = Image.open(\"raw_scan.png\").convert(\"RGB\")\nimg.thumbnail((4000, 4000))\nimg.save(\"ref.jpg\", quality=85)\ninputs = {\"reference_image_path\": \"ref.jpg\"}","handlingStrategy":"validation","validationCode":"from pathlib import Path\nMAX_BYTES = 10 * 1024 * 1024  # keep in sync with the tool's cap\nassert Path(ref).stat().st_size < MAX_BYTES, f\"{ref} too large\"","typeGuard":null,"tryCatchPattern":"try:\n    tool.run(inputs)\nexcept ValueError as e:\n    if \"must be smaller than\" in str(e):\n        compress_image(ref)  # resize/re-encode then retry with the smaller file\n        tool.run(inputs)\n    else:\n        raise","preventionTips":["Standardize reference assets: JPEG q85 for images, 128kbps audio — they will always fit.","For oversized media, prefer a public URL reference over local inlining."],"tags":["python","validation","file-size","reference","seedance"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}