lllyasviel/Fooocus · error · TypeError
"suffix" must be a string or tuple of strings
Error message
"suffix" must be a string or tuple of strings
What it means
scandir()'s suffix parameter must be a str or a tuple of str (or None for no filtering). Passing any other type — most commonly a list — raises TypeError immediately, because os.path.endswith only accepts str/tuple. This mirrors mmcv's scandin helper semantics.
Source
Thrown at extras/facexlib/utils/misc.py:96
return cached_file
def scandir(dir_path, suffix=None, recursive=False, full_path=False):
"""Scan a directory to find the interested files.
Args:
dir_path (str): Path of the directory.
suffix (str | tuple(str), optional): File suffix that we are
interested in. Default: None.
recursive (bool, optional): If set to True, recursively scan the
directory. Default: False.
full_path (bool, optional): If set to True, include the dir_path.
Default: False.
Returns:
A generator for all the interested files with relative paths.
"""
if (suffix is not None) and not isinstance(suffix, (str, tuple)):
raise TypeError('"suffix" must be a string or tuple of strings')
root = dir_path
def _scandir(dir_path, suffix, recursive):
for entry in os.scandir(dir_path):
if not entry.name.startswith('.') and entry.is_file():
if full_path:
return_path = entry.path
else:
return_path = osp.relpath(entry.path, root)
if suffix is None:
yield return_path
elif return_path.endswith(suffix):
yield return_path
else:
if recursive:
yield from _scandir(entry.path, suffix=suffix, recursive=recursive)View on GitHub (pinned to ae05379cc9)
Solutions
- Convert to tuple: scandir(dir, suffix=('.png', '.jpg')) or scandir(dir, tuple(ext_list)).
- For a single extension, pass a bare string: suffix='.png'.
- Pass suffix=None to accept all files and filter afterwards.
- If the list comes from YAML/JSON config, coerce with tuple(cfg['extensions']) at the call site.
Example fix
# before
files = list(scandir(img_dir, suffix=['.png', '.jpg']))
# after
files = list(scandir(img_dir, suffix=('.png', '.jpg'))) Defensive patterns
Strategy: type-guard
Validate before calling
if suffix is not None and not isinstance(suffix, (str, tuple)):
suffix = tuple(suffix) # coerce lists from YAML/JSON configs
assert suffix is None or isinstance(suffix, (str, tuple)) Type guard
def is_valid_suffix(s) -> bool:
return s is None or isinstance(s, str) or (isinstance(s, tuple) and all(isinstance(x, str) for x in s)) Try / catch
try:
files = list(scandir(dir_path, suffix=suffix))
except TypeError as e:
raise ValueError(f'Invalid suffix {suffix!r}: use str or tuple of str') from e Prevention
- Always write extension filters as tuples ('.png', '.jpg'), never lists.
- Coerce config-driven lists with tuple(...) at the boundary.
- Wrap third-party scandir calls in a thin helper that normalizes suffix first.
When it happens
Trigger: Calling scandir(dir_path, suffix=['.png', '.jpg']) (list instead of tuple), suffix=('.png',) is fine but suffix=b'.png' or suffix=Path('.png') is not. Also triggered by helpers that forward a user-supplied extension list verbatim.
Common situations: Refactoring code that used glob/glob2 and passing list literals; config files that define extensions as YAML lists which arrive as Python lists.
Related errors
- {model_name} is not implemented.
- No paddings to do, output_size must be None or {}
- Not (0 <= inner_padding_factor <= 1.0)
- Not (outer_padding[0] < output_size[0] and outer_padding[1]
- Must have (output_size - outer_padding)= some_scale * (crop_
AI-assisted analysis of lllyasviel/Fooocus@ae05379cc9 (2026-08-15).
Data as JSON: /api/errors/92a1c3b57870fd1c.
Report an issue: GitHub.