deepfakes/faceswap · error · FaceswapError

Error writing to '{filename}': {err.strerror}

Error message

Error writing to '{filename}': {err.strerror}

What it means

Serializer.save wraps file-write IOErrors: opening or writing the serialized file failed (permission denied, disk full, directory missing, path is a directory) and faceswap re-raises as FaceswapError including the OS strerror. The filename may have had the serializer's default extension appended by _check_extension.

Source

Thrown at lib/serializer.py:77

            The path to where the serialized file should be saved
        data: varies
            The data that is to be serialized to file

        Example
        ------
        >>> serializer = get_serializer('json')
        >>> data ['foo', 'bar']
        >>> json_file = '/path/to/json/file.json'
        >>> serializer.save(json_file, data)
        """
        logger.debug("filename: %s, data type: %s", filename, type(data))
        filename = self._check_extension(filename)
        try:
            with open(filename, self._write_option) as s_file:
                s_file.write(self.marshal(data))
        except IOError as err:
            msg = f"Error writing to '{filename}': {err.strerror}"
            raise FaceswapError(msg) from err

    def _check_extension(self, filename):
        """ Check the filename has an extension. If not add the correct one for the serializer """
        extension = os.path.splitext(filename)[1]
        retval = filename if extension else f"{filename}.{self.file_extension}"
        logger.debug("Original filename: '%s', final filename: '%s'", filename, retval)
        return retval

    def load(self, filename):
        """ Load data from an existing serialized file

        Parameters
        ----------
        filename: str
            The path to the serialized file

        Returns
        ----------

View on GitHub (pinned to f530cb7508)

Solutions

  1. Create the parent directory before saving: os.makedirs(os.path.dirname(filename), exist_ok=True).
  2. Free disk space / raise quota if strerror mentions space.
  3. Fix permissions on the target directory or choose a writable location.

Example fix

import os
from lib.serializer import get_serializer

# before
get_serializer('json').save('/out/missing/state.json', data)  # IOError -> FaceswapError

# after
os.makedirs('/out/missing', exist_ok=True)
get_serializer('json').save('/out/missing/state.json', data)
Defensive patterns

Strategy: validation

Validate before calling

import os

os.makedirs(os.path.dirname(filename) or '.', exist_ok=True)
assert os.access(os.path.dirname(filename) or '.', os.W_OK), 'no write permission'

Try / catch

try:
    serializer.save(filename, data)
except FaceswapError as err:
    if 'Error writing' in str(err):
        serializer.save(fallback_filename, data)  # e.g. /tmp fallback
    else:
        raise

Prevention

When it happens

Trigger: Saving a state/alignments file to a non-existent directory, read-only location, full disk, or path where a directory of the same name exists.

Common situations: Output dir never created (faceswap usually mkdirs, custom callers may not); disk quota exhausted on long training runs writing state files; permissions on config dirs.

Related errors


AI-assisted analysis of deepfakes/faceswap@f530cb7508 (2026-08-15). Data as JSON: /api/errors/7f1e92c97e807702. Report an issue: GitHub.