calesthio/OpenMontage · error · HTTPException
no poster frame available
Error message
no poster frame available
What it means
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.
Source
Thrown at backlot/server.py:260
# ---- Thumbnails (downscaled, cached on disk) ------------------------
@app.get("/thumb/{project_id}/{file_path:path}")
async def thumb(project_id: str, file_path: str, w: int = 640) -> FileResponse:
project_dir = _safe_project_dir(project_id)
target = (project_dir / file_path).resolve()
try:
target.relative_to(project_dir.resolve())
except ValueError:
raise HTTPException(status_code=403, detail="path escapes project")
if not target.is_file():
raise HTTPException(status_code=404, detail="media not found")
width = min(THUMB_WIDTHS, key=lambda x: abs(x - w))
cached = await asyncio.to_thread(_thumbnail_for, target, width)
if cached is None:
# Never fall back to raw video bytes for an <img> consumer (F-03);
# non-thumbable images are safe to serve as-is.
if target.suffix.lower() in {".mp4", ".webm", ".mov"}:
raise HTTPException(status_code=404, detail="no poster frame available")
return FileResponse(target)
return FileResponse(cached, media_type="image/jpeg")
# ---- Media (range requests handled by FileResponse) ---------------
@app.get("/media/{project_id}/{file_path:path}")
async def media(project_id: str, file_path: str) -> FileResponse:
project_dir = _safe_project_dir(project_id)
target = (project_dir / file_path).resolve()
try:
target.relative_to(project_dir.resolve())
except ValueError:
raise HTTPException(status_code=403, detail="path escapes project")
if not target.is_file():
raise HTTPException(status_code=404, detail="media not found")
return FileResponse(target)
# ---- UI ------------------------------------------------------------View on GitHub (pinned to 95e1c3d0ab)
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.
Example fix
# before
inputs = {"reference_image_path": "raw_scan.png"} # 40MB
# after
from PIL import Image
img = Image.open("raw_scan.png").convert("RGB")
img.thumbnail((4000, 4000))
img.save("ref.jpg", quality=85)
inputs = {"reference_image_path": "ref.jpg"} Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
MAX_BYTES = 10 * 1024 * 1024 # keep in sync with the tool's cap
assert Path(ref).stat().st_size < MAX_BYTES, f"{ref} too large" Try / catch
try:
tool.run(inputs)
except ValueError as e:
if "must be smaller than" in str(e):
compress_image(ref) # resize/re-encode then retry with the smaller file
tool.run(inputs)
else:
raise Prevention
- Standardize reference assets: JPEG q85 for images, 128kbps audio — they will always fit.
- For oversized media, prefer a public URL reference over local inlining.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- media not found
- invalid project id
- unknown project: {project_id}
- Unknown or invalid style_playbook {style_playbook!r}. Availa
- Artifact {artifact_name!r} failed schema validation: {exc}
AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15).
Data as JSON: /api/errors/a6264061f07c3b88.
Report an issue: GitHub.