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.

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)

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.