Lightning-AI/pytorch-lightning · error · MisconfigurationException

Invalid value for save_top_k={self.save_top_k}. Must be >= -

Error message

Invalid value for save_top_k={self.save_top_k}. Must be >= -1

What it means

ModelCheckpoint's `save_top_k` must be >= -1 (0 saves nothing, -1 saves all, k>0 keeps the k best). `__validate_init_configuration`, called from `__init__`, raises MisconfigurationException for anything below -1.

Source

Thrown at src/lightning/pytorch/callbacks/model_checkpoint.py:668

        # if `check_val_every_n_epoch != 1`, we can't say when the validation dataloader will be loaded
        # so let's not enforce saving at every training epoch end
        if trainer.check_val_every_n_epoch != 1:
            return False

        # no validation means save on train epoch end
        num_val_batches = (
            sum(trainer.num_val_batches) if isinstance(trainer.num_val_batches, list) else trainer.num_val_batches
        )
        if num_val_batches == 0:
            return True

        # if the user runs validation multiple times per training epoch, then we run after validation
        # instead of on train epoch end
        return trainer.val_check_interval == 1.0

    def __validate_init_configuration(self) -> None:
        if self.save_top_k < -1:
            raise MisconfigurationException(f"Invalid value for save_top_k={self.save_top_k}. Must be >= -1")
        if self._every_n_train_steps < 0:
            raise MisconfigurationException(
                f"Invalid value for every_n_train_steps={self._every_n_train_steps}. Must be >= 0"
            )
        if self._every_n_epochs < 0:
            raise MisconfigurationException(f"Invalid value for every_n_epochs={self._every_n_epochs}. Must be >= 0")

        every_n_train_steps_triggered = self._every_n_train_steps >= 1
        every_n_epochs_triggered = self._every_n_epochs >= 1
        train_time_interval_triggered = self._train_time_interval is not None
        if every_n_train_steps_triggered + every_n_epochs_triggered + train_time_interval_triggered > 1:
            raise MisconfigurationException(
                f"Combination of parameters every_n_train_steps={self._every_n_train_steps}, "
                f"every_n_epochs={self._every_n_epochs} and train_time_interval={self._train_time_interval} "
                "should be mutually exclusive."
            )

        if self.monitor is None and self.save_top_k not in (-1, 0, 1):

View on GitHub (pinned to 9fed5c27d2)

Solutions

  1. Use save_top_k=-1 (all), 0 (none), or a positive integer for k-best
  2. Guard computed values: `max(save_top_k, -1)`
  3. Remember separate knobs every_n_train_steps / every_n_epochs control frequency, not count

Example fix

# before
ModelCheckpoint(monitor='val_loss', save_top_k=-2)
# after
ModelCheckpoint(monitor='val_loss', save_top_k=-1)  # keep all checkpoints
Defensive patterns

Strategy: type-guard

Validate before calling

save_top_k = max(int(save_top_k), -1)
assert save_top_k >= -1

Type guard

def valid_save_top_k(v) -> bool:
    return isinstance(v, int) and not isinstance(v, bool) and v >= -1

Prevention

When it happens

Trigger: `ModelCheckpoint(save_top_k=-2)` or a computed value that goes negative. Validated at construction, so it fails before the Trainer runs.

Common situations: Config math like `save_top_k=num_checkpoints - 3` going negative; confusing semantics with every_n_epochs; typos or YAML values parsed as unexpected numbers.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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