ATH-MaaS/Pixelle-Video · error · FileNotFoundError

Generated media file not found: {local_path}

Error message

Generated media file not found: {local_path}

What it means

_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.

Source

Thrown at pixelle_video/services/frame_processor.py:479

            estimated_duration = file_size / 2000
            return max(1.0, estimated_duration)  # At least 1 second
    
    async def _download_media(
        self,
        url: str,
        frame_index: int,
        task_id: str,
        media_type: str
    ) -> str:
        """Download media (image or video) from URL to local file"""
        import os
        from pixelle_video.utils.os_util import get_task_frame_path
        output_path = get_task_frame_path(task_id, frame_index, media_type)

        if url.startswith("file://"):
            local_path = url[7:]
            if not os.path.exists(local_path):
                raise FileNotFoundError(f"Generated media file not found: {local_path}")
            return local_path

        if os.path.exists(url):
            return url
        
        timeout = httpx.Timeout(connect=10.0, read=60, write=60, pool=60)
        async with httpx.AsyncClient(timeout=timeout) as client:
            response = await client.get(url)
            response.raise_for_status()
            
            with open(output_path, 'wb') as f:
                f.write(response.content)
        
        return output_path
    
    async def _get_video_duration(self, video_path: str) -> float:
        """Get video duration in seconds"""
        try:

View on GitHub (pinned to 848b054e4f)

Solutions

  1. Check the exact path in the message (strip file://) with ls/stat; verify the generating step actually completed and wrote the file.
  2. 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.
  3. Confirm task_id/frame_index/path construction (get_task_frame_path) matches where the generator actually saved the file.
  4. Add retry/wait logic if the file may appear asynchronously, or fail the media step upstream if its output is missing.
  5. Re-run the generation step for the affected frame if the artifact was cleaned up.

Example fix

// before
local_path = url[7:]
if not os.path.exists(local_path):
    raise FileNotFoundError(f"Generated media file not found: {local_path}")

// after
local_path = url[7:]
for _ in range(5):
    if os.path.exists(local_path):
        break
    await asyncio.sleep(1)
else:
    raise FileNotFoundError(
        f"Generated media file not found after wait: {local_path} "
        f"(task_id={task_id}, frame={frame_index})"
    )
Defensive patterns

Strategy: validation

Validate before calling

import os
def ensure_local_media(url: str) -> str:
    if url.startswith("file://"):
        p = url[7:]
        if not os.path.exists(p):
            raise FileNotFoundError(f"pre-check failed, generated file absent: {p}")
        return p
    return url

ensure_local_media(media_result.url)  # before continuing the pipeline

Try / catch

try:
    local = await processor_step(frame)
except FileNotFoundError as e:
    logger.error("generated artifact missing: %s", e)
    # re-run generation for this frame or switch to shared/remote storage

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of ATH-MaaS/Pixelle-Video@848b054e4f (2026-08-30). Data as JSON: /api/errors/e9b432a9687a4a16. Report an issue: GitHub.