{"record":{"id":"aa4343940a665af0","repo":"ytdl-org/youtube-dl","slug":"vidme-said-this-video-has-been-suspended-either-d","errorCode":null,"errorMessage":"Vidme said: This video has been suspended either due to a copyright claim, or for violating the terms of use.","messagePattern":"Vidme said: This video has been suspended either due to a copyright claim, or for violating the terms of use\\.","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/vidme.py","lineNumber":160,"sourceCode":"            if isinstance(e.cause, compat_HTTPError) and e.cause.code == 400:\n                response = self._parse_json(e.cause.read(), video_id)\n            else:\n                raise\n\n        error = response.get('error')\n        if error:\n            raise ExtractorError(\n                '%s returned error: %s' % (self.IE_NAME, error), expected=True)\n\n        video = response['video']\n\n        if video.get('state') == 'deleted':\n            raise ExtractorError(\n                'Vidme said: Sorry, this video has been deleted.',\n                expected=True)\n\n        if video.get('state') in ('user-disabled', 'suspended'):\n            raise ExtractorError(\n                'Vidme said: This video has been suspended either due to a copyright claim, '\n                'or for violating the terms of use.',\n                expected=True)\n\n        formats = []\n        for f in video.get('formats', []):\n            format_url = url_or_none(f.get('uri'))\n            if not format_url:\n                continue\n            format_type = f.get('type')\n            if format_type == 'dash':\n                formats.extend(self._extract_mpd_formats(\n                    format_url, video_id, mpd_id='dash', fatal=False))\n            elif format_type == 'hls':\n                formats.extend(self._extract_m3u8_formats(\n                    format_url, video_id, 'mp4', entry_protocol='m3u8_native',\n                    m3u8_id='hls', fatal=False))\n            else:","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/vidme.py#L142-L178","documentation":"Raised by the Vidme extractor when response['video']['state'] is 'user-disabled' or 'suspended' — the uploader disabled the video or Vidme suspended it for a copyright claim / ToS violation. The long message spells out both causes. expected=True, terminal content state.","triggerScenarios":"Extracting a vid.me URL whose API payload has video.state in ('user-disabled', 'suspended') — DMCA'd uploads or uploader-disabled content.","commonSituations":"Copyright-claimed music uploads (the classic Vidme case); accounts suspended wholesale before the service shut down; legacy links in comments/articles.","solutions":["The video is unavailable by enforcement decision — no download is possible.","Find a legal mirror or the original source of the content.","Filter vid.me URLs out of crawlers/download queues.","Report the skip reason to the user as a copyright/enforcement removal, not a bug."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"state = get_nested(fetch_json(api_url), 'video', 'state')\nif state in ('user-disabled', 'suspended'):\n    skip(video_id, 'vidme enforcement removal: %s' % state)","typeGuard":null,"tryCatchPattern":"try:\n    ydl.extract_info(url)\nexcept ExtractorError as e:\n    if e.expected and 'suspended' in str(e):\n        archive_dead(url)  # copyright/ToS removal: permanent, do not alert\n    raise","preventionTips":["Report copyright/enforcement removals as skips, not errors, in monitoring.","Never retry enforcement-based removals.","Maintain per-URL outcome caches for large archives."],"tags":["content-missing","copyright","service-shutdown","expected-error"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}