ytdl-org/youtube-dl · error · HTTPError
Is a directory: %s
Error message
Is a directory: %s
What it means
Raised inside the AVM2 interpreter loop when bytecode calls a property on the String class object itself (callproperty with obj == StringClass) and the method name is anything other than the 'String' constructor. swfinterp simply has no implementations for String's static methods, so any SWF that calls e.g. String.fromCharCode hits this NotImplementedError mid-execution.
Source
Thrown at devscripts/buildserver.py:361
super(YoutubeDLBuilder, self).build()
class DownloadBuilder(object):
def __init__(self, **kwargs):
self.handler = kwargs.pop('handler')
self.srcPath = os.path.join(self.buildPath, *tuple(kwargs['path'][2:]))
self.srcPath = os.path.abspath(os.path.normpath(self.srcPath))
if not self.srcPath.startswith(self.buildPath):
raise HTTPError(self.srcPath, 401)
super(DownloadBuilder, self).__init__(**kwargs)
def build(self):
if not os.path.exists(self.srcPath):
raise HTTPError('No such file', 404)
if os.path.isdir(self.srcPath):
raise HTTPError('Is a directory: %s' % self.srcPath, 401)
self.handler.send_response(200)
self.handler.send_header('Content-Type', 'application/octet-stream')
self.handler.send_header('Content-Disposition', 'attachment; filename=%s' % os.path.split(self.srcPath)[-1])
self.handler.send_header('Content-Length', str(os.stat(self.srcPath).st_size))
self.handler.end_headers()
with open(self.srcPath, 'rb') as src:
shutil.copyfileobj(src, self.handler.wfile)
super(DownloadBuilder, self).build()
class CleanupTempDir(object):
def build(self):
try:
rmtree(self.basePath)
except Exception as e:View on GitHub (pinned to 956b8c5855)
Solutions
- Extend the StringClass branch in swfinterp.py to handle the needed static method (fromCharCode is a two-line addition using chr()).
- Use patch_function to replace the calling method with a Python implementation so the unsupported call is never executed.
- Update youtube-dl or use yt-dlp, where the algorithm is typically reimplemented natively.
Example fix
# before (swfinterp.py, callproperty on StringClass)
else:
raise NotImplementedError(
'Function String.%s is not yet implemented' % mname)
# after
elif mname == 'fromCharCode':
res = ''.join(chr(a) for a in args)
stack.append(res)
continue
else:
raise NotImplementedError(
'Function String.%s is not yet implemented' % mname) Defensive patterns
Strategy: fallback
Try / catch
try:
result = func(args)
except NotImplementedError as e:
if 'Function String.' in str(e):
# e.g. String.fromCharCode — supply it via a patched caller
interpreter.patch_function(avm_class, caller_name,
lambda a: py_equivalent(a))
result = func(args)
else:
raise Prevention
- Extend the StringClass callproperty branch with the static methods your SWFs use (fromCharCode is trivial).
- Patch the calling ActionScript method with Python instead of relying on interpreter coverage.
- Treat NotImplementedError from swfinterp as 'interpreter gap', not corruption — the message names the exact missing builtin.
When it happens
Trigger: Interpreted ActionScript executes String.<something>(...) as a static call — String.fromCharCode(code) is by far the most common in signature-scrambling players. The interpreter's callproperty branch matches obj == StringClass, mname != 'String', and raises.
Common situations: A site's player SWF uses String.fromCharCode in its signature algorithm; youtube-dl's interpreter runs it and dies. Appears suddenly when the site rotates its player, since old players happened not to use that call.
Related errors
- Invalid syntax in Cookie Header
- Invalid value %r in format specification %r
- Invalid filter specification %r
- Missing mandatory parameter "%s"
- Invalid repository "%s"
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/1fdb2b31abb3786f.
Report an issue: GitHub.