{"record":{"id":"971a673c23a5a0da","repo":"ytdl-org/youtube-dl","slug":"message-dynamic-from-service-error-response-erro","errorCode":null,"errorMessage":"message (dynamic from service error response, error.get('message'))","messagePattern":"message \\(dynamic from service error response, error\\.get\\('message'\\)\\)","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"warning","filePath":"youtube_dl/extractor/adn.py","lineNumber":225,"sourceCode":"                        'withMetadata': 'true',\n                        'source': 'Web'\n                    })\n                break\n            except ExtractorError as e:\n                if not isinstance(e.cause, compat_HTTPError):\n                    raise e\n\n                if e.cause.code == 401:\n                    # This usually goes away with a different random pkcs1pad, so retry\n                    continue\n\n                error = self._parse_json(\n                    self._webpage_read_content(e.cause, links_url, video_id),\n                    video_id, fatal=False) or {}\n                message = error.get('message')\n                if e.cause.code == 403 and error.get('code') == 'player-bad-geolocation-country':\n                    self.raise_geo_restricted(msg=message)\n                raise ExtractorError(message)\n        else:\n            raise ExtractorError('Giving up retrying')\n\n        links = links_data.get('links') or {}\n        metas = links_data.get('metadata') or {}\n        sub_url = (links.get('subtitles') or {}).get('all')\n        video_info = links_data.get('video') or {}\n        title = metas['title']\n\n        formats = []\n        for format_id, qualities in (links.get('streaming') or {}).items():\n            if not isinstance(qualities, dict):\n                continue\n            for quality, load_balancer_url in qualities.items():\n                load_balancer_data = self._download_json(\n                    load_balancer_url, video_id,\n                    'Downloading %s %s JSON metadata' % (format_id, quality),\n                    fatal=False) or {}","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/adn.py#L207-L243","documentation":"Raised by the fallback _unlock_file stub on platforms without fcntl/msvcrt (the same ImportError branch as the lock stub). Release of a locked_file raises IOError(UNSUPPORTED_MSG). In practice you normally hit the lock-side error first, so this one surfaces mainly when code constructs or patches around locking but still uses the unlock path (e.g. locked_file.__exit__ after a no-op lock was injected).","triggerScenarios":"On a no-fcntl runtime: entering any locked_file would already fail at _lock_file; this specific raise appears when _lock_file was monkeypatched/bypassed but __exit__ still calls the stub _unlock_file, or when library code calls _unlock_file directly.","commonSituations":"Embedders on Jython/IronPython who patched only one of the two stubs; copy-pasted locking wrappers calling utils._unlock_file directly; test environments simulating platforms by hiding fcntl.","solutions":["Monkeypatch both stubs symmetrically: utils._lock_file = lambda f, e: None and utils._unlock_file = lambda f: None.","Prefer running under CPython where real locking exists rather than patching half the API.","Avoid calling _lock_file/_unlock_file directly; use the locked_file context manager so both sides stay consistent.","Update youtube-dl / use yt-dlp, whose file handling no longer relies on these paths in the same way."],"exampleFix":"# before (partial patch — unlock still raises)\nyoutube_dl.utils._lock_file = lambda f, exclusive: None\n\n# after (patch both sides)\nyoutube_dl.utils._lock_file = lambda f, exclusive: None\nyoutube_dl.utils._unlock_file = lambda f: None","handlingStrategy":"try-catch","validationCode":"def file_locking_supported():\n    if sys.platform == 'win32':\n        return True\n    try:\n        import fcntl  # noqa: F401\n        return True\n    except ImportError:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    with locked_file(path, 'w') as f:\n        f.write(data)\nexcept IOError as e:\n    if 'file locking is not supported' in str(e):\n        with open(path, 'w') as f:  # accept single-process, unlocked fallback\n            f.write(data)\n    else:\n        raise","preventionTips":["When monkeypatching the locking stubs, always replace _lock_file AND _unlock_file together.","Use the locked_file context manager rather than calling _unlock_file directly.","Probe for fcntl at startup on non-Windows platforms and document the limitation."],"tags":["platform-support","file-locking","compatibility","monkeypatch"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}