{"record":{"id":"e5dcc031c7e94197","repo":"ATH-MaaS/Pixelle-Video","slug":"failed-to-concatenate-videos-e","errorCode":null,"errorMessage":"Failed to concatenate videos: {e}","messagePattern":"Failed to concatenate videos: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"pixelle_video/services/video.py","lineNumber":253,"sourceCode":"            \n            # Run command\n            import subprocess\n            result = subprocess.run(\n                cmd,\n                capture_output=True,\n                text=True,\n                check=True\n            )\n            \n            logger.success(f\"Videos concatenated successfully: {output}\")\n            return output\n        except subprocess.CalledProcessError as e:\n            error_msg = e.stderr if e.stderr else str(e)\n            logger.error(f\"FFmpeg concat filter error: {error_msg}\")\n            raise RuntimeError(f\"Failed to concatenate videos: {error_msg}\")\n        except Exception as e:\n            logger.error(f\"Concatenation error: {e}\")\n            raise RuntimeError(f\"Failed to concatenate videos: {e}\")\n    \n    def _get_video_duration(self, video: str) -> float:\n        \"\"\"Get video duration in seconds\"\"\"\n        try:\n            probe = ffmpeg.probe(video)\n            duration = float(probe['format']['duration'])\n            return duration\n        except Exception as e:\n            logger.warning(f\"Failed to get video duration: {e}\")\n            return 0.0\n    \n    def _get_audio_duration(self, audio: str) -> float:\n        \"\"\"Get audio duration in seconds\"\"\"\n        try:\n            probe = ffmpeg.probe(audio)\n            duration = float(probe['format']['duration'])\n            return duration\n        except Exception as e:","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/ATH-MaaS/Pixelle-Video/blob/848b054e4fae40dabc62ec58e960b573e83793ac/pixelle_video/services/video.py#L235-L271","documentation":"This is the generic catch-all in _concat_filter: any exception that is not CalledProcessError (e.g. OSError, TypeError, ffmpeg-python parse errors) is logged and re-raised as this RuntimeError. It signals an unexpected failure during filter-based concatenation rather than a documented ffmpeg exit code.","triggerScenarios":"Non-subprocess failures during concat: unreadable files raising OSError, None/invalid entries in the videos list breaking string formatting, disk full during output write, unexpected library exceptions.","commonSituations":"Passing Path objects or None mixed into the list; disk quota exceeded on long encodes; filesystem errors on network mounts; bugs in calling code that corrupts the input list mid-flight.","solutions":["Check the wrapped message and the logged 'Concatenation error' line for the underlying exception type.","Sanitize the videos list: ensure all entries are existing, non-None str paths.","Check disk space and permissions for the output location.","If the cause is an ffmpeg exit failure, look for the sibling CalledProcessError path (error 123) behavior and fix inputs accordingly."],"exampleFix":"// before\nservice.concat_videos([pathlib.Path('a.mp4'), None, 'b.mp4'], 'out.mp4')  # generic failure\n// after\nclean = [str(p) for p in (a, b) if p and os.path.isfile(str(p))]\nservice.concat_videos(clean, 'out.mp4')","handlingStrategy":"try-catch","validationCode":"videos = [str(v) for v in videos if v and os.path.isfile(str(v))]\nif not videos:\n    raise ValueError('no valid inputs after filtering')","typeGuard":"def all_str_paths(videos: object) -> bool:\n    return isinstance(videos, list) and all(isinstance(v, str) for v in videos)","tryCatchPattern":"try:\n    service.concat_videos(videos, out)\nexcept RuntimeError as e:\n    if 'Failed to concatenate videos' in str(e):\n        logger.exception('unexpected concat failure')  # underlying exception type is in message/log\n    else:\n        raise","preventionTips":["Pass plain str paths (not Path/None) in the videos list.","Check free disk space before re-encoding large outputs.","Avoid mutating the input list while the job runs (async/threads).","Keep catch logs (logger.exception) enabled so the underlying exception type is visible."],"tags":["ffmpeg","concat","unexpected-exception"],"backgroundTag":"ffmpeg-concat-failed","analyzedSha":"848b054e4fae40dabc62ec58e960b573e83793ac","analyzedAt":"2026-08-30T03:24:41.468Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}