{"record":{"id":"b7f1e43371795e27","repo":"ATH-MaaS/Pixelle-Video","slug":"unknown-media-type-frame-media-type","errorCode":null,"errorMessage":"Unknown media type: {frame.media_type}","messagePattern":"Unknown media type: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pixelle_video/services/frame_processor.py","lineNumber":441,"sourceCode":"            # Clean up temp file\n            import os\n            if os.path.exists(temp_video_with_overlay):\n                os.unlink(temp_video_with_overlay)\n        \n        elif frame.media_type == \"image\" or frame.media_type is None:\n            # Image workflow: Use composed image directly\n            # The asset_default.html template includes the image in the composition\n            logger.debug(f\"  → Using image-based composition\")\n            \n            segment_path = video_service.create_video_from_image(\n                image=frame.composed_image_path,\n                audio=frame.audio_path,\n                output=output_path,\n                fps=config.video_fps\n            )\n        \n        else:\n            raise ValueError(f\"Unknown media type: {frame.media_type}\")\n        \n        frame.video_segment_path = segment_path\n        \n        logger.debug(f\"  ✓ Video segment created: {segment_path}\")\n    \n    async def _get_audio_duration(self, audio_path: str) -> float:\n        \"\"\"Get audio duration in seconds\"\"\"\n        try:\n            # Try using ffmpeg-python\n            import ffmpeg\n            probe = ffmpeg.probe(audio_path)\n            duration = float(probe['format']['duration'])\n            return duration\n        except Exception as e:\n            logger.warning(f\"Failed to get audio duration: {e}, using estimate\")\n            # Fallback: estimate based on file size (very rough)\n            import os\n            file_size = os.path.getsize(audio_path)","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/ATH-MaaS/Pixelle-Video/blob/848b054e4fae40dabc62ec58e960b573e83793ac/pixelle_video/services/frame_processor.py#L423-L459","documentation":"In _step_create_video_segment, the processor switches on frame.media_type to decide how to build the video segment; any value other than the known kinds (e.g. 'image' or 'video') reaches the else and raises ValueError. It is a second, independent media-type dispatch point from [107], operating on the storyboard frame rather than the media result.","triggerScenarios":"Running the pipeline (__call__ -> _step_create_video_segment) with a StoryboardFrame whose media_type is misspelled, mixed-case, empty, or a newly introduced type that this branch (and its ffmpeg/imageio composition path) does not handle.","commonSituations":"Storyboard JSON authored by hand or by an LLM containing media_type like 'Image' or 'gif'; schema drift between the storyboard generator and the processor; a new media kind added upstream without updating this switch.","solutions":["Inspect frame.media_type at failure and fix the storyboard/config to use the exact expected literal ('image' or 'video').","Normalize with frame.media_type.strip().lower() before dispatch.","Validate storyboard frames at load time against an allowed set of media types so errors surface before expensive media generation.","If a new type is intended, extend _step_create_video_segment with a branch that composes a segment for it."],"exampleFix":"// before\nelse:\n    raise ValueError(f\"Unknown media type: {frame.media_type}\")\n\n// after\nmedia_type = (frame.media_type or \"\").strip().lower()\nif media_type not in (\"image\", \"video\"):\n    raise ValueError(f\"Unknown media type: {frame.media_type!r}\")\n# dispatch on normalized media_type","handlingStrategy":"validation","validationCode":"ALLOWED_FRAME_TYPES = {\"image\", \"video\"}\ndef validate_storyboard(frames) -> None:\n    for i, f in enumerate(frames):\n        mt = (getattr(f, \"media_type\", \"\") or \"\").strip().lower()\n        if mt not in ALLOWED_FRAME_TYPES:\n            raise ValueError(f\"frame {i}: bad media_type {f.media_type!r}\")\n\nvalidate_storyboard(storyboard.frames)  # before calling the processor","typeGuard":"def is_supported_frame(frame) -> bool:\n    mt = getattr(frame, \"media_type\", None)\n    return isinstance(mt, str) and mt.strip().lower() in {\"image\", \"video\"}","tryCatchPattern":"try:\n    await processor(storyboard, config)\nexcept ValueError as e:\n    if \"Unknown media type\" in str(e):\n        logger.error(\"storyboard frame media_type invalid: %s\", e)\n        # regenerate/repair storyboard, skip frame, or abort pipeline\n    else:\n        raise","preventionTips":["Validate all StoryboardFrame.media_type values when loading/authoring storyboards, not mid-pipeline.","Author storyboards programmatically from a fixed enum instead of hand-written strings.","Keep the storyboard schema and processor dispatch branches in sync via a shared constant list."],"tags":["validation","enum","value-error","python"],"backgroundTag":"unknown-media-type","analyzedSha":"848b054e4fae40dabc62ec58e960b573e83793ac","analyzedAt":"2026-08-30T03:24:41.468Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}