{"record":{"id":"e9b432a9687a4a16","repo":"ATH-MaaS/Pixelle-Video","slug":"generated-media-file-not-found-local-path","errorCode":null,"errorMessage":"Generated media file not found: {local_path}","messagePattern":"Generated media file not found: (.+?)","errorType":"validation","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"pixelle_video/services/frame_processor.py","lineNumber":479,"sourceCode":"            estimated_duration = file_size / 2000\n            return max(1.0, estimated_duration)  # At least 1 second\n    \n    async def _download_media(\n        self,\n        url: str,\n        frame_index: int,\n        task_id: str,\n        media_type: str\n    ) -> str:\n        \"\"\"Download media (image or video) from URL to local file\"\"\"\n        import os\n        from pixelle_video.utils.os_util import get_task_frame_path\n        output_path = get_task_frame_path(task_id, frame_index, media_type)\n\n        if url.startswith(\"file://\"):\n            local_path = url[7:]\n            if not os.path.exists(local_path):\n                raise FileNotFoundError(f\"Generated media file not found: {local_path}\")\n            return local_path\n\n        if os.path.exists(url):\n            return url\n        \n        timeout = httpx.Timeout(connect=10.0, read=60, write=60, pool=60)\n        async with httpx.AsyncClient(timeout=timeout) as client:\n            response = await client.get(url)\n            response.raise_for_status()\n            \n            with open(output_path, 'wb') as f:\n                f.write(response.content)\n        \n        return output_path\n    \n    async def _get_video_duration(self, video_path: str) -> float:\n        \"\"\"Get video duration in seconds\"\"\"\n        try:","sourceCodeStart":461,"sourceCodeEnd":497,"githubUrl":"https://github.com/ATH-MaaS/Pixelle-Video/blob/848b054e4fae40dabc62ec58e960b573e83793ac/pixelle_video/services/frame_processor.py#L461-L497","documentation":"_download_media resolves a generated media URL into a local path. When the URL uses the file:// scheme it strips the prefix and requires the local file to exist; if os.path.exists fails it raises FileNotFoundError. The upstream media generation step reported success, but its declared output artifact is absent on disk.","triggerScenarios":"Calling the pipeline when a provider/task returns a file:// URL (e.g. from a local generation worker or mounted volume) whose path was deleted, never created, or written to a different host/container filesystem; also reachable from _prepare_api_video_inputs for API video inputs.","commonSituations":"Distributed runs where the generating worker's local disk is not shared with the processor; temp-directory cleanup removing the file before download; wrong task_id/paths baked into the returned URL; race where the file write has not been flushed.","solutions":["Check the exact path in the message (strip file://) with ls/stat; verify the generating step actually completed and wrote the file.","Ensure the storage path is on a shared volume when generator and processor run in different containers/hosts — use object storage URLs (http) instead of file:// across machines.","Confirm task_id/frame_index/path construction (get_task_frame_path) matches where the generator actually saved the file.","Add retry/wait logic if the file may appear asynchronously, or fail the media step upstream if its output is missing.","Re-run the generation step for the affected frame if the artifact was cleaned up."],"exampleFix":"// before\nlocal_path = url[7:]\nif not os.path.exists(local_path):\n    raise FileNotFoundError(f\"Generated media file not found: {local_path}\")\n\n// after\nlocal_path = url[7:]\nfor _ in range(5):\n    if os.path.exists(local_path):\n        break\n    await asyncio.sleep(1)\nelse:\n    raise FileNotFoundError(\n        f\"Generated media file not found after wait: {local_path} \"\n        f\"(task_id={task_id}, frame={frame_index})\"\n    )","handlingStrategy":"validation","validationCode":"import os\ndef ensure_local_media(url: str) -> str:\n    if url.startswith(\"file://\"):\n        p = url[7:]\n        if not os.path.exists(p):\n            raise FileNotFoundError(f\"pre-check failed, generated file absent: {p}\")\n        return p\n    return url\n\nensure_local_media(media_result.url)  # before continuing the pipeline","typeGuard":null,"tryCatchPattern":"try:\n    local = await processor_step(frame)\nexcept FileNotFoundError as e:\n    logger.error(\"generated artifact missing: %s\", e)\n    # re-run generation for this frame or switch to shared/remote storage","preventionTips":["Run generator and consumer against a shared volume or object storage; avoid file:// URLs across hosts.","Disable aggressive temp cleanup (or lengthen retention) for generation output directories.","Have the generation step verify its own output exists (and is non-empty) before reporting success.","Log task_id and resolved paths on both writer and reader sides so path mismatches are obvious."],"tags":["file-not-found","filesystem","artifact","python"],"backgroundTag":"file-not-found","analyzedSha":"848b054e4fae40dabc62ec58e960b573e83793ac","analyzedAt":"2026-08-30T03:24:41.468Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}