{"record":{"id":"7c4353a1ef7f98b1","repo":"calesthio/OpenMontage","slug":"media-not-found","errorCode":null,"errorMessage":"media not found","messagePattern":"media not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"backlot/server.py","lineNumber":253,"sourceCode":"                hub.unsubscribe(q)\n\n        return StreamingResponse(stream(), media_type=\"text/event-stream\", headers={\n            \"Cache-Control\": \"no-cache\",\n            \"X-Accel-Buffering\": \"no\",\n        })\n\n    # ---- 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())","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/backlot/server.py#L235-L271","documentation":"Raised while resolving a reference (image/audio) that is neither a data: URI, an http(s):// or asset:// URL, nor an existing local file path. The tool checks the prefix first, then Path(value).is_file(); when both fail, the reference is unusable and rejected before any upload/encoding.","triggerScenarios":"Passing reference_image_url=\"/home/me/missing.png\" (typo or wrong working directory), a relative path that does not exist from the process cwd, an ftp:// or file:// URL, or a bare filename with no such file on disk.","commonSituations":"Agent runs in a container/sandbox where the path from a previous step was never copied in; relative paths resolved against a different cwd; ssh:// or s3:// style URIs the tool cannot consume.","solutions":["Verify the path exists from the process's working directory (use an absolute path via Path(...).resolve()).","For remote storage (s3, ftp), download the file locally first or expose it behind a public https URL.","For previously generated media in the pipeline, pass its asset:// ID instead of a filesystem path."],"exampleFix":"# before\ninputs = {\"reference_image_path\": \"~/inputs/ref.png\"}\n# after\nfrom pathlib import Path\ninputs = {\"reference_image_path\": str(Path(\"~/inputs/ref.png\").expanduser().resolve())}","handlingStrategy":"validation","validationCode":"def resolve_ref(value):\n    from pathlib import Path\n    s = str(value)\n    if s.startswith((\"http://\", \"https://\", \"asset://\", \"data:\")):\n        return s\n    p = Path(s).expanduser().resolve()\n    if not p.is_file():\n        raise FileNotFoundError(p)\n    return str(p)","typeGuard":"def is_usable_ref(v) -> bool:\n    from pathlib import Path\n    s = str(v)\n    return s.startswith((\"http://\", \"https://\", \"asset://\", \"data:\")) or Path(s).expanduser().is_file()","tryCatchPattern":"try:\n    tool.run(inputs)\nexcept ValueError as e:\n    if \"must be a public URL\" in str(e):\n        log_missing_ref(inputs)  # surface which reference path failed\n        raise","preventionTips":["Always expanduser().resolve() local reference paths before passing them.","For cross-step pipelines, pass asset:// IDs of previously generated media rather than filesystem paths."],"tags":["python","validation","file-not-found","reference","seedance"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}