{"record":{"id":"03bc20d6201ca27c","repo":"xtekky/gpt4free","slug":"operation-failed-after-retries-attempts","errorCode":null,"errorMessage":"Operation failed after {retries} attempts.","messagePattern":"Operation failed after (.+?) attempts\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"g4f/integration/markitdown/_youtube_converter.py","lineNumber":313,"sourceCode":"                if k == key:\n                    return json[k]\n                if result := self._findKey(v, key):\n                    return result\n        return None\n\n    def _retry_operation(self, operation, retries=3, delay=2):\n        \"\"\"Retries the operation if it fails.\"\"\"\n        attempt = 0\n        while attempt < retries:\n            try:\n                return operation()  # Attempt the operation\n            except Exception as e:\n                print(f\"Attempt {attempt + 1} failed: {e}\")\n                if attempt < retries - 1:\n                    time.sleep(delay)  # Wait before retrying\n                attempt += 1\n        # If all attempts fail, raise the last exception\n        raise Exception(f\"Operation failed after {retries} attempts.\")\n","sourceCodeStart":295,"sourceCodeEnd":314,"githubUrl":"https://github.com/xtekky/gpt4free/blob/973504e1770928ed5fb82f43da528f441ad9ddc3/g4f/integration/markitdown/_youtube_converter.py#L295-L314","documentation":"Raised by MarkItDown's YouTube converter _retry_operation() after every attempt of the wrapped operation raised an exception within the retry budget (default 3 attempts, 2s delay). The printed 'Attempt N failed' lines carry the real cause; this final Exception only signals exhaustion, and it discards the last exception object (message only via prints).","triggerScenarios":"Transcript/caption fetching for a YouTube URL failing 3 times in a row — typical causes: network/proxy blocks YouTube, the video has no captions, YouTube changed its page/schema and pytube/yt-dlp data extraction breaks, or an HTTP 429/403 rate limit persists across retries.","commonSituations":"Server IPs (cloud providers) blocked by YouTube; videos with captions disabled; version drift between the vendored converter and YouTube's HTML; rate limiting under batch conversion jobs.","solutions":["Check the preceding 'Attempt N failed: ...' console output — it holds the root-cause message; fix that (e.g. 403 => proxy/VPN, HTTPError => missing captions).","Test the same URL with yt-dlp --write-auto-sub locally to see if captions are obtainable at all.","Update the yt-dlp/pytube dependency to the latest version, since YouTube extraction breaks frequently.","For batch jobs, add backoff or slow down; wrap the convert call in try/except and skip un-captioned videos."],"exampleFix":"// before\nresult = md.convert(\"https://www.youtube.com/watch?v=XXXX\")  # raises generic Exception after 3 attempts\n\n// after\ntry:\n    result = md.convert(\"https://www.youtube.com/watch?v=XXXX\")\nexcept Exception as e:\n    logger.warning(\"youtube transcript unavailable for %s: %s\", url, e)\n    result = None  # graceful skip in batch processing","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    result = md.convert(youtube_url)\nexcept Exception as e:\n    if \"Operation failed after\" in str(e):\n        logger.warning(\"youtube extraction failed for %s; check captions/network\", youtube_url)\n        result = None\n    else:\n        raise","preventionTips":["Check caption availability and network reachability before batch-converting playlists.","Keep yt-dlp/pytube current; YouTube extraction breaks often.","Treat the console 'Attempt N failed' lines as the real diagnostics."],"tags":["markitdown","youtube","retry","network"],"backgroundTag":null,"analyzedSha":"973504e1770928ed5fb82f43da528f441ad9ddc3","analyzedAt":"2026-08-14T23:45:32.408Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}