Lightning-AI/pytorch-lightning · error · ValueError

`.{fn}(ckpt_path="best")` is set but `ModelCheckpoint` is no

Error message

`.{fn}(ckpt_path="best")` is set but `ModelCheckpoint` is not configured to save the best model.

What it means

Raised when ckpt_path="best" is requested, a ModelCheckpoint exists, but its best_model_path is empty because it was never configured to track a best model (no monitor) and nothing was saved. Resolving "best" is impossible without a monitored metric.

Source

Thrown at src/lightning/pytorch/trainer/connectors/checkpoint_connector.py:175

        if ckpt_path == "best":
            if len(self.trainer.checkpoint_callbacks) > 1:
                rank_zero_warn(
                    f'`.{fn}(ckpt_path="best")` is called with Trainer configured with multiple `ModelCheckpoint`'
                    " callbacks. It will use the best checkpoint path from first checkpoint callback."
                )

            if not self.trainer.checkpoint_callback:
                raise ValueError(f'`.{fn}(ckpt_path="best")` is set but `ModelCheckpoint` is not configured.')

            has_best_model_path = self.trainer.checkpoint_callback.best_model_path
            if hasattr(self.trainer.checkpoint_callback, "best_model_path") and not has_best_model_path:
                if self.trainer.fast_dev_run:
                    raise ValueError(
                        f'You cannot execute `.{fn}(ckpt_path="best")` with `fast_dev_run=True`.'
                        f" Please pass an exact checkpoint path to `.{fn}(ckpt_path=...)`"
                    )
                raise ValueError(
                    f'`.{fn}(ckpt_path="best")` is set but `ModelCheckpoint` is not configured to save the best model.'
                )
            # load best weights
            ckpt_path = getattr(self.trainer.checkpoint_callback, "best_model_path", None)

        elif ckpt_path == "last":
            candidates = {getattr(ft, "ckpt_path", None) for ft in ft_checkpoints}
            for callback in self.trainer.checkpoint_callbacks:
                if isinstance(callback, ModelCheckpoint):
                    candidates |= callback._find_last_checkpoints(self.trainer)
            candidates_fs = {path: get_filesystem(path) for path in candidates if path}
            candidates_ts = {path: fs.modified(path) for path, fs in candidates_fs.items() if fs.exists(path)}
            if not candidates_ts:
                # not an error so it can be set and forget before the first `fit` run
                rank_zero_warn(
                    f'.{fn}(ckpt_path="last") is set, but there is no last checkpoint available.'
                    " No checkpoint will be loaded. HINT: Set `ModelCheckpoint(..., save_last=True)`."
                )

View on GitHub (pinned to 9fed5c27d2)

Solutions

  1. Configure ModelCheckpoint with a monitor: ModelCheckpoint(monitor="val_loss", mode="min", save_top_k=1)
  2. Pass the explicit checkpoint file path to ckpt_path
  3. Ensure validation runs (provide val_dataloaders) so the monitored metric is logged

Example fix

# before
trainer = Trainer(callbacks=[ModelCheckpoint()])
trainer.fit(model)
trainer.test(ckpt_path="best")
# after
trainer = Trainer(callbacks=[ModelCheckpoint(monitor="val_loss", mode="min", save_top_k=1)])
trainer.fit(model)
trainer.test(ckpt_path="best")
Defensive patterns

Strategy: validation

Validate before calling

from lightning.pytorch.callbacks import ModelCheckpoint
mc = ModelCheckpoint(monitor="val_loss", mode="min", save_top_k=1)
assert mc.monitor is not None, "set monitor so best_model_path is populated"

Try / catch

try:
    trainer.test(ckpt_path="best")
except ValueError as e:
    if "save the best model" in str(e):
        trainer.test(ckpt_path=mc.last_model_path or explicit)
    else:
        raise

Prevention

When it happens

Trigger: Trainer(callbacks=[ModelCheckpoint()]) with default settings (no monitor) or save_top_k=0, followed by trainer.test(ckpt_path="best"); also when fit did not run validation so the monitored metric never fired.

Common situations: Evaluating after training with a bare ModelCheckpoint; forgetting to set monitor when the model logs multiple metrics; calling .test(ckpt_path="best") before .fit() has completed an epoch with validation.

Related errors


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