{"record":{"id":"55bc64626c1ab69d","repo":"xai-org/x-algorithm","slug":"container-is-not-an-inputcontainer-type-containe","errorCode":null,"errorMessage":"Container is not an InputContainer: {type(container).__name__}","messagePattern":"Container is not an InputContainer: (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"warning","filePath":"grox/libs/video_tools/video_frames.py","lineNumber":65,"sourceCode":"            tile_size,\n            enable_clahe,\n            include_combined_video_bytes,\n        )\n\n    @classmethod\n    def _extract_frames(\n        cls,\n        video_bytes: bytes,\n        max_frames: int,\n        tile_size: int | None,\n        enable_clahe: bool = False,\n        include_combined_video_bytes: bool = True,\n    ) -> VideoData:\n        logger.info(f\"Extracting maximum {max_frames} frames from video\")\n\n        with av.open(io.BytesIO(video_bytes)) as container:\n            if not isinstance(container, InputContainer):\n                raise TypeError(\n                    f\"Container is not an InputContainer: {type(container).__name__}\"\n                )\n            c_duration = container.duration\n            if not c_duration:\n                logger.warning(\"No duration found for video\")\n                c_duration = 0\n            total_duration = float(c_duration / av.time_base)\n            sample_times = cls._sample_frames(total_duration, max_frames)\n            frames = cls._extract_frames_at_times(container, sample_times)\n        for frame in frames:\n            frame.frame = cls._process_frame(frame.frame, tile_size, enable_clahe)\n        logger.info(f\"Extracted {len(frames)} frames\")\n        combined_bytes = (\n            cls.get_video_bytes([frame.frame for frame in frames])\n            if include_combined_video_bytes\n            else None\n        )\n        return VideoData(","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/grox/libs/video_tools/video_frames.py#L47-L83","documentation":"_extract_frames opens the video with PyAV and asserts the returned container is an av.InputContainer. av.open(io.BytesIO(...)) should always yield an InputContainer for readable byte streams, so this TypeError firing indicates an unexpected PyAV return type — classically an output container, or an av version/typing change. It is effectively a defensive invariant check.","triggerScenarios":"A PyAV version where av.open on this input returns a container class not (re)exported as the av.InputContainer the module imported — i.e. identity isinstance check failing due to duplicated module imports or a renamed class; or code paths feeding something av treats as writable, returning OutputContainer.","commonSituations":"Upgrading/downgrading PyAV (av) so the InputContainer symbol used for isinstance no longer matches the actual runtime class; mixing av built against different FFmpeg; monkeypatching/mocking av in tests causing type mismatch.","solutions":["Pin/align the av package to the version this code was built against (check the project's lock/requirements).","If it persists, replace the isinstance identity check or compare container.__class__.__name__ / use av.logging diagnostics; report upstream.","In tests, avoid mocking av.open with objects that are not real InputContainer instances."],"exampleFix":"# before\nwith av.open(io.BytesIO(video_bytes)) as container:\n    if not isinstance(container, InputContainer):  # TypeError on av version drift\n        raise TypeError(...)\n\n# after (pin the dependency instead of changing logic)\n# requirements.txt: av==14.0.1  (match the version the library was tested with)","handlingStrategy":"type-guard","validationCode":"# guard at the dependency level before extracting frames\nimport av\nassert tuple(int(x) for x in av.__version__.split('.')[:2]) >= (14, 0), 'unsupported PyAV'","typeGuard":"import av\ndef is_input_container(c: object) -> bool:\n    return isinstance(c, av.input.InputContainer) or type(c).__name__ == 'InputContainer'","tryCatchPattern":"try:\n    frames = extract_frames(video_bytes)\nexcept TypeError as e:\n    if 'InputContainer' in str(e):\n        logger.error('PyAV version mismatch; pin av to the supported version')\n    raise","preventionTips":["Pin the av version in requirements/lockfiles","Don't mock av.open with foreign objects in tests","Run dependency compatibility checks in CI"],"tags":["pyav","video","type-check","version-mismatch","defensive-check"],"backgroundTag":"library-version-incompatibility","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}