Lightning-AI/pytorch-lightning · error · ValueError

Primitives {_PRIMITIVE_TYPES} are not allowed.

Error message

Primitives {_PRIMITIVE_TYPES} are not allowed.

What it means

_to_hparams_dict (used by save_hyperparameters/_set_hparams) only accepts mappings, argparse.Namespace, and a few structured config types. Python primitives (str, int, float, bool, etc. in _PRIMITIVE_TYPES) are rejected because hparams must be a key-value structure, not a single scalar.

Source

Thrown at src/lightning/pytorch/core/mixins/hparams_mixin.py:161

        This allows derived classes to drop hyperparameters previously saved
        by base classes.

        Args:
            ignore_list: Names of hyperparameters to remove.

        """
        for key in ignore_list:
            self._hparams.pop(key, None)

    @staticmethod
    def _to_hparams_dict(hp: Union[MutableMapping, Namespace, str]) -> Union[MutableMapping, AttributeDict]:
        if isinstance(hp, Namespace):
            hp = vars(hp)
        if isinstance(hp, dict):
            hp = AttributeDict(hp)
        elif isinstance(hp, _PRIMITIVE_TYPES):
            raise ValueError(f"Primitives {_PRIMITIVE_TYPES} are not allowed.")
        elif not isinstance(hp, _ALLOWED_CONFIG_TYPES):
            raise ValueError(f"Unsupported config type of {type(hp)}.")
        return hp

    @property
    def hparams(self) -> Union[AttributeDict, MutableMapping]:
        """The collection of hyperparameters saved with :meth:`save_hyperparameters`. It is mutable by the user. For
        the frozen set of initial hyperparameters, use :attr:`hparams_initial`.

        Returns:
            Mutable hyperparameters dictionary

        """
        if not hasattr(self, "_hparams"):
            self._hparams = AttributeDict()
        return self._hparams

    @property

View on GitHub (pinned to 9fed5c27d2)

Solutions

  1. Wrap the value in a dict: save_hyperparameters({'model_name': 'resnet18'})
  2. Pass keyword arguments: save_hyperparameters(model_name='resnet18')
  3. Use an argparse.Namespace or AttributeDict for structured configs

Example fix

# before
self.save_hyperparameters('resnet18')

# after
self.save_hyperparameters({'arch': 'resnet18'})
Defensive patterns

Strategy: type-guard

Validate before calling

from argparse import Namespace
if not isinstance(hp, (dict, Namespace)) and isinstance(hp, (str, int, float, bool)):
    hp = {'value': hp}  # wrap primitives before save_hyperparameters

Type guard

def is_valid_hparams(obj) -> bool:
    return isinstance(obj, (dict, MutableMapping, Namespace)) or type(obj).__name__ in _ALLOWED_CONFIG_TYPE_NAMES

Try / catch

try:
    self.save_hyperparameters(hp)
except ValueError as e:
    if 'Primitives' in str(e):
        self.save_hyperparameters({'value': hp})
    else:
        raise

Prevention

When it happens

Trigger: Calling model.save_hyperparameters("some_string") or save_hyperparameters(42); passing a bare primitive to LightningModule(save_hyperparameters=...) or _set_hparams.

Common situations: User tried save_hyperparameters('resnet18') intending to store a model name scalar; passed a single value instead of a dict from a config loader.

Related errors


AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28). Data as JSON: /api/errors/b69fe9f86d984696. Report an issue: GitHub.