ytdl-org/youtube-dl · error · BuildError

Invalid path

Error message

Invalid path

What it means

Thrown by youtube-dl's SWF bytecode interpreter when the bytes passed to _extract_tags do not start with a valid SWF signature. A real SWF file begins with 'FWS' (uncompressed), 'CWS' (zlib-compressed), or 'ZWS' (LZMA); this code checks bytes 1-3 for 'WS'. Getting an ExtractorError here means the downloaded payload was HTML/JSON (often an error page) rather than the expected SWF file.

Source

Thrown at devscripts/buildserver.py:300

                break
            except Exception:
                pass

        if not python_path:
            raise BuildError('No such Python version: %s' % python_version)

        self.pythonPath = python_path

        super(PythonBuilder, self).__init__(**kwargs)


class GITInfoBuilder(object):
    def __init__(self, **kwargs):
        try:
            self.user, self.repoName = kwargs['path'][:2]
            self.rev = kwargs.pop('rev')
        except ValueError:
            raise BuildError('Invalid path')
        except KeyError as e:
            raise BuildError('Missing mandatory parameter "%s"' % e.args[0])

        path = os.path.join(os.environ['APPDATA'], 'Build archive', self.repoName, self.user)
        if not os.path.exists(path):
            os.makedirs(path)
        self.basePath = tempfile.mkdtemp(dir=path)
        self.buildPath = os.path.join(self.basePath, 'build')

        super(GITInfoBuilder, self).__init__(**kwargs)


class GITBuilder(GITInfoBuilder):
    def build(self):
        try:
            subprocess.check_output(['git', 'clone', 'git://github.com/%s/%s.git' % (self.user, self.repoName), self.buildPath])
            subprocess.check_output(['git', 'checkout', self.rev], cwd=self.buildPath)
        except subprocess.CalledProcessError as e:

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Update youtube-dl (youtube-dl -U) or switch to yt-dlp — SWF URL and deciphering logic rot quickly and are fixed in releases.
  2. Fetch the SWF URL manually (curl) and inspect the first bytes: if it is HTML, the site no longer serves that player; find the new player URL from the page source.
  3. If you call swfinterp yourself, validate the payload starts with b'FWS'/b'CWS'/b'ZWS' before interpreting.
  4. As an extractor maintainer, refresh the SWF URL extraction so it is read from the watch page rather than hard-coded.

Example fix

# before
interpreter = SWFInterpreter(swf_bytes)  # may raise on non-SWF payload

# after
if swf_bytes[1:3] != b'WS':
    raise ExtractorError('Expected SWF player, got %r' % swf_bytes[:20])
interpreter = SWFInterpreter(swf_bytes)
Defensive patterns

Strategy: validation

Validate before calling

def is_swf(data):
    return len(data) >= 3 and data[:3] in (b'FWS', b'CWS', b'ZWS')

# before interpreting:
# assert is_swf(swf_bytes), 'server did not return an SWF'

Type guard

def is_swf(data: bytes) -> bool:
    return len(data) >= 3 and data[1:3] == b'WS' and data[0:1] in (b'F', b'C', b'Z')

Try / catch

from youtube_dl.utils import ExtractorError
from youtube_dl.swfinterp import SWFInterpreter
try:
    interp = SWFInterpreter(swf_bytes)
except ExtractorError as e:
    if 'Not an SWF file' in str(e):
        raise ExtractorError('Player URL returned non-SWF content (site changed?) — update youtube-dl')
    raise

Prevention

When it happens

Trigger: An extractor calls SWFInterpreter on content fetched from a hard-coded SWF URL (used to decipher signatures or compute keys, e.g. for signed CDN URLs). The check triggers when bytes 1:3 != b'WS': the server returned a 200 HTML page, a redirect body, a CAPTCHA/login wall, or the file format changed. Direct API use of swfinterp._extract_tags / SWFInterpreter with non-SWF bytes also triggers it.

Common situations: A site changed its player SWF location or stopped serving SWF players entirely (moved to HTML5/JS); a geo-block or CDN error page is served instead of the SWF; an outdated youtube-dl with stale SWF URLs; passing a local file that is not Flash.

Related errors


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