deepfakes/faceswap · error · ValueError

[{self._name}] Expected {self.datatype} got {type(value)} ({

Error message

[{self._name}] Expected {self.datatype} got {type(value)} ({value})

What it means

ConfigOption.validate special-case for options whose choices == 'colorchooser' (GUI color pickers): the value must be a 7-character string starting with '#'. Values like 'ff0000' (missing hash), '#ff00' (too short) or '#ff0000ff' (8 digits) raise ValueError.

Source

Thrown at lib/config/objects.py:390

            The value to set this item to. Must be of type :attr:`datatype`

        Raises
        ------
        ValueError
            If the given value does not pass type and content validation checks
        """
        if not self._name:
            raise ValueError("The name of this object should have been set before any value is"
                             "added")

        if self.datatype is list:
            if not isinstance(value, (str, list)):
                raise ValueError(f"[{self._name}] List values should be set as a Str or List. Got "
                                 f"{type(value)} ({value})")
            value = cast(T, self._parse_list(value))

        if not isinstance(value, self.datatype):
            raise ValueError(
                f"[{self._name}] Expected {self.datatype} got {type(value)} ({value})")

        if isinstance(self.choices, list) and self.choices:
            assert isinstance(value, (list, str))
            value = cast(T, self._validate_selection(value))

        if self.choices == "colorchooser":
            assert isinstance(value, str)
            if not value.startswith("#") or len(value) != 7:
                raise ValueError(f"Hex color codes should start with a '#' and be 6 "
                                 f"characters long. Got: '{value}'")

        self._value = value

    def set_name(self, name: str) -> None:
        """Set the logging name for this object for display purposes

        Parameters

View on GitHub (pinned to f530cb7508)

Solutions

  1. Normalize to '#rrggbb' before setting: f"#{value.lstrip('#')[:6].lower()}" then verify len == 7
  2. Convert from numeric colors: '#%02x%02x%02x' % (r, g, b)
  3. Use the GUI colorchooser control, which always yields a valid string

Example fix

# before
option.set("ff0000")     # missing '#'
option.set("00ff00ff")   # 8 digits

# after
r, g, b = 255, 0, 0
option.set("#%02x%02x%02x" % (r, g, b))  # '#ff0000'
Defensive patterns

Strategy: type-guard

Validate before calling

def coerce(value, datatype):
    if datatype is bool and isinstance(value, str):
        return value.strip().lower() in ("true", "yes", "on", "1")
    if datatype in (int, float) and isinstance(value, str):
        return datatype(value.strip('"\' '))
    if datatype is str and isinstance(value, bytes):
        return value.decode()
    return value

option.set(coerce(raw, option.datatype))

Type guard

def matches_datatype(value, datatype) -> bool:
    """True when value passes ConfigOption's isinstance check."""
    if datatype is float:
        return isinstance(value, (int, float)) and not isinstance(value, bool)
    if datatype is bool:
        return isinstance(value, bool)
    return isinstance(value, datatype)

Try / catch

try:
    option.set(value)
except ValueError as err:
    if "Expected" in str(err):
        option.set(coerce(value, option.datatype))
    else:
        raise

Prevention

When it happens

Trigger: Setting a colorchooser-typed option (e.g. mask/display colors in GUI plugins) with a bare hex string, an 8-digit ARGB hex, a CSS color name ('red'), or a value with trailing whitespace.

Common situations: Hand-editing an .ini and dropping the '#'; copying colors from CSS/design tools that emit #RGB or rgb() notation; scripts writing colors from libraries that use 0x-prefixed ints.

Related errors


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