ytdl-org/youtube-dl · warning · ExtractorError

message (dynamic from service error response, error.get('mes

Error message

message (dynamic from service error response, error.get('message'))

What it means

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).

Source

Thrown at youtube_dl/extractor/adn.py:225

                        'withMetadata': 'true',
                        'source': 'Web'
                    })
                break
            except ExtractorError as e:
                if not isinstance(e.cause, compat_HTTPError):
                    raise e

                if e.cause.code == 401:
                    # This usually goes away with a different random pkcs1pad, so retry
                    continue

                error = self._parse_json(
                    self._webpage_read_content(e.cause, links_url, video_id),
                    video_id, fatal=False) or {}
                message = error.get('message')
                if e.cause.code == 403 and error.get('code') == 'player-bad-geolocation-country':
                    self.raise_geo_restricted(msg=message)
                raise ExtractorError(message)
        else:
            raise ExtractorError('Giving up retrying')

        links = links_data.get('links') or {}
        metas = links_data.get('metadata') or {}
        sub_url = (links.get('subtitles') or {}).get('all')
        video_info = links_data.get('video') or {}
        title = metas['title']

        formats = []
        for format_id, qualities in (links.get('streaming') or {}).items():
            if not isinstance(qualities, dict):
                continue
            for quality, load_balancer_url in qualities.items():
                load_balancer_data = self._download_json(
                    load_balancer_url, video_id,
                    'Downloading %s %s JSON metadata' % (format_id, quality),
                    fatal=False) or {}

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Monkeypatch both stubs symmetrically: utils._lock_file = lambda f, e: None and utils._unlock_file = lambda f: None.
  2. Prefer running under CPython where real locking exists rather than patching half the API.
  3. Avoid calling _lock_file/_unlock_file directly; use the locked_file context manager so both sides stay consistent.
  4. Update youtube-dl / use yt-dlp, whose file handling no longer relies on these paths in the same way.

Example fix

# before (partial patch — unlock still raises)
youtube_dl.utils._lock_file = lambda f, exclusive: None

# after (patch both sides)
youtube_dl.utils._lock_file = lambda f, exclusive: None
youtube_dl.utils._unlock_file = lambda f: None
Defensive patterns

Strategy: try-catch

Validate before calling

def file_locking_supported():
    if sys.platform == 'win32':
        return True
    try:
        import fcntl  # noqa: F401
        return True
    except ImportError:
        return False

Try / catch

try:
    with locked_file(path, 'w') as f:
        f.write(data)
except IOError as e:
    if 'file locking is not supported' in str(e):
        with open(path, 'w') as f:  # accept single-process, unlocked fallback
            f.write(data)
    else:
        raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14). Data as JSON: /api/errors/971a673c23a5a0da. Report an issue: GitHub.