deepfakes/faceswap · error · ValueError

Dictionary keys {sorted(inbound)} should be a subset of data

Error message

Dictionary keys {sorted(inbound)} should be a subset of dataclass params {sorted(all_fields)}

What it means

Companion check in the same from_dict loader: every dataclass field that has no default/default_factory must be present in the incoming dict. Missing required keys raise ValueError so partially-initialized objects cannot be silently created.

Source

Thrown at lib/align/objects.py:175

            items.append(v)
        retval = T.cast(list[T.Any] | tuple[T.Any], tuple(items) if origin is tuple else items)
        return retval

    @classmethod
    def from_dict(cls, data_dict: dict[str, T.Any]) -> T.Self:
        """Load the contents from a serialized python dict into this dataclass

        Parameters
        ----------
        data_dict
            The data to load into the dataclass
        """
        inbound = set(data_dict)
        all_fields = set(f.name for f in fields(cls))
        required = set(f.name for f in fields(cls)
                       if f.default is MISSING and f.default_factory is MISSING)
        if not inbound.issubset(all_fields):
            raise ValueError(f"Dictionary keys {sorted(inbound)} should be a subset of dataclass "
                             f"params {sorted(all_fields)}")
        if not required.issubset(inbound):
            raise ValueError(f"Dataclass params {sorted(required)} should be a subset of "
                             f"dictionary keys {sorted(inbound)}")
        type_hints = T.get_type_hints(cls)
        kwargs: dict[str, T.Any] = {}
        for f in fields(cls):
            if f.name not in data_dict:
                continue
            field_type = type_hints.get(f.name)
            val = data_dict[f.name]
            converted = cls._convert_dtype(field_type, val)
            if converted is not None:
                kwargs[f.name] = converted
                continue
            if isinstance(val, dict):
                kwargs[f.name] = cls._parse_dict(field_type, val)
                continue

View on GitHub (pinned to f530cb7508)

Solutions

  1. Run the alignments migration for the file (alignments tool / extract job under a supported version, see the version guidance in Alignments.load)
  2. Supply defaults explicitly before from_dict: data.setdefault(field, default) for each missing required field
  3. Regenerate alignments from scratch with the current version

Example fix

# before
partial = {"mask": [], "detected_faces": []}  # missing 'landmarks'
face = Alignment.from_dict(partial)  # ValueError

# after
partial.setdefault("landmarks", np.zeros((68, 2), dtype="float32"))
partial.setdefault("landmark_type", LandmarkType.LM_2D_68)
face = Alignment.from_dict(partial)
Defensive patterns

Strategy: validation

Validate before calling

from dataclasses import fields

def sanitize_for(cls, data):
    valid = {f.name for f in fields(cls)}
    return {k: v for k, v in data.items() if k in valid}

Try / catch

try:
    obj = MyDataclass.from_dict(payload)
except ValueError as err:
    if "should be a subset of dataclass params" in str(err):
        obj = MyDataclass.from_dict(sanitize_for(MyDataclass, payload))
    else:
        raise

Prevention

When it happens

Trigger: cls.from_dict(data) where data omits a required field (e.g. an Alignment dict without 'landmarks' or 'landmark_type'); often the result of forwarding an old-format dict through the check in error 4 after dropping keys.

Common situations: Older alignments format missing newer mandatory fields (pre-2.x files before migration); partial manual dict construction; tests using fixture dicts that were never updated after a field was added.

Related errors


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