deepfakes/faceswap · error · ValueError

The given shape {shape} is not valid. Valid shapes: {list(sh

Error message

The given shape {shape} is not valid. Valid shapes: {list(shapes)}

What it means

Raised in the dataclass from_dict loader mixin (lib/align/objects.py, used by AlignedFace/Alignment/DetectedFace serialized data) when the incoming dict contains keys that are not fields of the dataclass. It guards against schema drift between the serialized alignments file and the current code.

Source

Thrown at lib/align/constants.py:47

        shape
            The shape to get the landmark type for

        Returns
        -------
        The enum for the given shape

        Raises
        ------
        ValueError
            If the requested shape is not valid
        """
        shapes: dict[tuple[int, int], LandmarkType] = {(4, 2): cls.LM_2D_4,
                                                       (51, 2): cls.LM_2D_51,
                                                       (68, 2): cls.LM_2D_68,
                                                       (98, 2): cls.LM_2D_98,
                                                       (26, 3): cls.LM_3D_26}
        if shape not in shapes:
            raise ValueError(f"The given shape {shape} is not valid. Valid shapes: {list(shapes)}")
        return shapes[shape]


EXTRACT_RATIOS: dict[CenteringType, float] = {"legacy": 0.375, "face": 0.5, "head": 0.625}
"""The amount of padding applied to each centering type when generating aligned faces"""

MEAN_FACE: dict[LandmarkType, np.ndarray] = {
    LandmarkType.LM_2D_4: np.array(
        [[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]]),  # Clockwise from TL
    LandmarkType.LM_2D_51: np.array([
        [0.010086, 0.106454], [0.085135, 0.038915], [0.191003, 0.018748], [0.300643, 0.034489],
        [0.403270, 0.077391], [0.596729, 0.077391], [0.699356, 0.034489], [0.808997, 0.018748],
        [0.914864, 0.038915], [0.989913, 0.106454], [0.500000, 0.203352], [0.500000, 0.307009],
        [0.500000, 0.409805], [0.500000, 0.515625], [0.376753, 0.587326], [0.435909, 0.609345],
        [0.500000, 0.628106], [0.564090, 0.609345], [0.623246, 0.587326], [0.131610, 0.216423],
        [0.196995, 0.178758], [0.275698, 0.179852], [0.344479, 0.231733], [0.270791, 0.245099],
        [0.192616, 0.244077], [0.655520, 0.231733], [0.724301, 0.179852], [0.803005, 0.178758],
        [0.868389, 0.216423], [0.807383, 0.244077], [0.729208, 0.245099], [0.264022, 0.780233],

View on GitHub (pinned to f530cb7508)

Solutions

  1. Regenerate the alignments file with the Faceswap version you are running (re-run extraction)
  2. Update/checkout the Faceswap version that matches the file's '__meta__' version field and use its migration path (alignments tool 'extract' job)
  3. If hand-building dicts, remove unknown keys: {k: v for k, v in data.items() if k in field_names}

Example fix

# before
entry = {"x": 1, "y": 2, "landmarks_xy": pts, "bogus_key": 0}
aligned = Alignment.from_dict(entry)  # ValueError: bogus_key not a field

# after
from dataclasses import fields
valid = {f.name for f in fields(Alignment)}
aligned = Alignment.from_dict({k: v for k, v in entry.items() if k in valid})
Defensive patterns

Strategy: type-guard

Validate before calling

import cv2, numpy as np

VALID = {(4, 2), (51, 2), (68, 2), (98, 2), (26, 3)}

def load_landmarks(path):
    arr = np.loadtxt(path)
    if arr.ndim == 1:
        arr = arr.reshape(-1, arr.shape[-1] if arr.ndim else 2) if arr.size else arr
        arr = arr.reshape(-1, 2) if arr.size and arr.shape[0] not in (26,) else arr
    if tuple(arr.shape) not in VALID:
        raise ValueError(f"unsupported landmarks shape {arr.shape}; expected one of {VALID}")
    return arr

Type guard

from lib.align.constants import LandmarkType

_VALID_SHAPES = {(4, 2), (51, 2), (68, 2), (98, 2), (26, 3)}

def is_supported_landmarks(arr: "np.ndarray") -> bool:
    """Narrow arr to shapes LandmarkType.from_shape accepts."""
    return tuple(arr.shape) in _VALID_SHAPES

Try / catch

try:
    ltype = LandmarkType.from_shape(lms.shape)
except ValueError:
    logger.warning("skipping frame with landmarks shape %s", lms.shape)
    continue

Prevention

When it happens

Trigger: Calling cls.from_dict(data) (e.g. Alignment.from_dict) where data was produced by a different/older Faceswap version with renamed or extra fields, or a hand-crafted dict with a typo'd key like 'lmk_type' instead of 'landmark_type'.

Common situations: Loading alignments files written by a newer Faceswap into an older checkout (or vice versa); manually editing alignments JSON/pickle; a plugin writing non-schema keys into alignment entries.

Related errors


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