ytdl-org/youtube-dl · error · ValueError

Invalid filter specification %r

Error message

Invalid filter specification %r

What it means

The interpreter loop in swfinterp.extract_function implements a fixed subset of AVM2 opcodes (roughly 0xD0-0xD7 register ops plus many others up to 0xD7/0x77 seen in the surrounding elif chain). Any opcode byte without a matching branch raises NotImplementedError('Unsupported opcode %d'). It means the SWF's bytecode uses an instruction youtube-dl never implemented — common for exotic Flash compiler output.

Source

Thrown at youtube_dl/YoutubeDL.py:1279

                '*=': lambda attr, value: value in attr,
            }
            str_operator_rex = re.compile(r'''(?x)
                \s*(?P<key>ext|acodec|vcodec|container|protocol|format_id|language)
                \s*(?P<negation>!\s*)?(?P<op>%s)(?P<none_inclusive>\s*\?)?
                \s*(?P<value>[a-zA-Z0-9._-]+)
                \s*$
                ''' % '|'.join(map(re.escape, STR_OPERATORS.keys())))
            m = str_operator_rex.search(filter_spec)
            if m:
                comparison_value = m.group('value')
                str_op = STR_OPERATORS[m.group('op')]
                if m.group('negation'):
                    op = lambda attr, value: not str_op(attr, value)
                else:
                    op = str_op

        if not m:
            raise ValueError('Invalid filter specification %r' % filter_spec)

        def _filter(f):
            actual_value = f.get(m.group('key'))
            if actual_value is None:
                return m.group('none_inclusive')
            return op(actual_value, comparison_value)
        return _filter

    def _default_format_spec(self, info_dict, download=True):

        def can_merge():
            merger = FFmpegMergerPP(self)
            return merger.available and merger.can_merge()

        def prefer_best():
            if self.params.get('simulate', False):
                return False
            if not download:

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Identify the opcode via an AVM2 reference (the number in the message) and add an elif branch to the interpreter loop — nearby branches show the register/stack convention.
  2. patch_function the containing method with a Python reimplementation so the opcode is never executed.
  3. Update youtube-dl / use yt-dlp — or better, port the algorithm directly since SWF support is effectively frozen.
  4. Long term, stop depending on SWF interpretation: extract the algorithm and reimplement it.

Example fix

# before (swfinterp.py interpreter loop tail)
else:
    raise NotImplementedError('Unsupported opcode %d' % opcode)

# after: e.g. opcode 0xA0 = add
elif opcode == 0xA0:  # add
    a2 = stack.pop()
    a1 = stack.pop()
    stack.append(a1 + a2)
else:
    raise NotImplementedError('Unsupported opcode %d' % opcode)
Defensive patterns

Strategy: fallback

Try / catch

try:
    out = func(args)
except NotImplementedError as e:
    import re
    m = re.search(r'Unsupported opcode (\d+)', str(e))
    if m:
        # opcode number identifies the missing AVM2 instruction;
        # implement it in the loop or patch the containing function
        opcode = int(m.group(1))
        raise ExtractorError('interpreter gap: AVM2 opcode %d' % opcode)
    raise

Prevention

When it happens

Trigger: Executing a method containing an unimplemented opcode: bit ops, type coercion instructions, exception handling (lookupswitch/throw), or anything produced by non-Adobe/obfuscating compilers. The numeric opcode in the message identifies exactly which instruction is missing.

Common situations: Site rotates to a player compiled with different settings or an obfuscator, introducing new opcodes in the deciphering function; attempts to interpret arbitrary ActionScript classes beyond the small surface youtube-dl needed.

Related errors


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