deepfakes/faceswap · error · FaceswapError

No display detected. GUI mode has been disabled.

Error message

No display detected. GUI mode has been disabled.

What it means

lib/config/ini.py resolves plugin config locations: if an explicit ini_path argument is given it must point to an existing file, otherwise ValueError. This guards typos before ConfigParser tries to read it.

Solutions

  1. Check the path with os.path.isfile before passing it, and fix the typo/missing file
  2. Create the file first (copy the default from <repo>/config/<plugin_group>.ini or let the tool generate one by omitting ini_path)
  3. If you meant the default location, pass ini_path=None instead of a bad path

Example fix

# before
cfg = FaceswapConfig(ini_path="config/my_plugin.ini")  # file absent -> ValueError

# after
import os
ini = "config/my_plugin.ini"
if not os.path.isfile(ini):
    shutil.copy("config/.faceswap.example", ini)
cfg = FaceswapConfig(ini_path=ini)
Defensive patterns

Strategy: validation

Validate before calling

import os

def display_available():
    return os.name == "nt" or bool(os.environ.get("DISPLAY"))

assert display_available(), "headless: use CLI subcommands or ssh -X"

Type guard

def can_open_gui() -> bool:
    """True on Windows or when a DISPLAY/X server is configured."""
    import os
    return os.name == "nt" or bool(os.environ.get("DISPLAY"))

Try / catch

from lib.utils import FaceswapError
try:
    launch_gui(args)
except FaceswapError as err:
    if "No display detected" in str(err):
        switch_to_cli_mode(args)
    else:
        raise

Prevention

When it happens

Trigger: Constructing the ini Config object (or calling its path resolver) with ini_path='/path/that/does/not/exist.ini'; passing a directory instead of a file; relative paths resolved against an unexpected cwd; stale path after a file was moved/deleted.

Common situations: Pointing a plugin at a custom config file that was never created; scripts passing os.path.dirname instead of the file itself; the config file deleted after a cleanup or not restored from backup.

Related errors


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

Appendix: source

Thrown at lib/cli/launcher.py:169

            logger.info("Fedora: sudo dnf install python3-tkinter")
            raise FaceswapError("TkInter not found") from err

    @classmethod
    def _check_display(cls) -> None:
        """Check whether there is a display to output the GUI to.

        If running on Windows then it is assumed that we are not running in headless mode

        Raises
        ------
        FaceswapError
            If a DISPLAY environmental variable cannot be found
        """
        if not os.environ.get("DISPLAY", None) and os.name != "nt":
            if platform.system() == "Darwin":
                logger.info("macOS users need to install XQuartz. "
                            "See https://support.apple.com/en-gb/HT201341")
            raise FaceswapError("No display detected. GUI mode has been disabled.")

    def execute_script(self, arguments: argparse.Namespace) -> None:
        """Performs final set up and launches the requested :attr:`_command` with the given
        command line arguments.

        Monitors for errors and attempts to shut down the process cleanly on exit.

        Parameters
        ----------
        arguments
            The command line arguments to be passed to the executing script.
        """
        is_gui = hasattr(arguments, "redirect_gui") and arguments.redirect_gui
        log_setup(arguments.loglevel, arguments.logfile, self._command, is_gui)
        success = False

        if self._command != "gui":
            self._configure_backend(arguments)

View on GitHub (pinned to f530cb7508)