Lightning-AI/pytorch-lightning · error · MisconfigurationException
`mode` can be {', '.join(self.mode_dict.keys())}, got {self.
Error message
`mode` can be {', '.join(self.mode_dict.keys())}, got {self.mode} What it means
EarlyStopping validates its `mode` argument against a fixed set (`min`, `max`) stored in `self.mode_dict`. Any other string raises a MisconfigurationException at callback construction time. The mode determines whether the monitored metric is minimized or maximized.
Source
Thrown at src/lightning/pytorch/callbacks/early_stopping.py:146
super().__init__()
self.monitor = monitor
self.min_delta = min_delta
self.patience = patience
self.verbose = verbose
self.mode = mode
self.strict = strict
self.check_finite = check_finite
self.stopping_threshold = stopping_threshold
self.divergence_threshold = divergence_threshold
self.wait_count = 0
self.stopped_epoch = 0
self.stopping_reason = EarlyStoppingReason.NOT_STOPPED
self.stopping_reason_message: Optional[str] = None
self._check_on_train_epoch_end = check_on_train_epoch_end
self.log_rank_zero_only = log_rank_zero_only
if self.mode not in self.mode_dict:
raise MisconfigurationException(f"`mode` can be {', '.join(self.mode_dict.keys())}, got {self.mode}")
self.min_delta *= 1 if self.monitor_op == torch.gt else -1
torch_inf = torch.tensor(torch.inf)
self.best_score = torch_inf if self.monitor_op == torch.lt else -torch_inf
@property
@override
def state_key(self) -> str:
return self._generate_state_key(monitor=self.monitor, mode=self.mode)
@override
def setup(self, trainer: "pl.Trainer", pl_module: "pl.LightningModule", stage: str) -> None:
if self._check_on_train_epoch_end is None:
# if the user runs validation multiple times per training epoch or multiple training epochs without
# validation, then we run after validation instead of on train epoch end
self._check_on_train_epoch_end = trainer.val_check_interval == 1.0 and trainer.check_val_every_n_epoch == 1
def _validate_condition_metric(self, logs: dict[str, Tensor]) -> bool:View on GitHub (pinned to 9fed5c27d2)
Solutions
- Set `mode='min'` for losses or `mode='max'` for metrics like accuracy — these are the only accepted values
- Check for casing/whitespace: 'Min', ' min ' are rejected
- If mode comes from a config file, validate it before constructing the callback
Example fix
// before EarlyStopping(monitor='val_loss', mode='minimum') // after EarlyStopping(monitor='val_loss', mode='min')
Defensive patterns
Strategy: validation
Validate before calling
from lightning.pytorch.callbacks.early_stopping import EarlyStopping
mode = 'min' # from config
assert mode in ('min', 'max'), f"mode must be min/max, got {mode!r}" Type guard
def is_valid_es_mode(mode: str) -> bool:
return isinstance(mode, str) and mode in ('min', 'max') Prevention
- Validate mode against ('min','max') in config-loading code
- Centralize callback construction in one factory with typed config (pydantic Literal['min','max'])
When it happens
Trigger: Instantiating `EarlyStopping(monitor='val_loss', mode='ascending')` or passing a typo like `mode='Min'` (case-sensitive) or `mode='minimum'`. The check runs in `__init__`, so it fails immediately when the callback is created, before any training.
Common situations: Typos or case mistakes in `mode`; copying config from another library that uses different mode names (e.g. 'auto', 'higher'); passing mode programmatically from a config value that is misspelled.
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
- logging_interval should be `step` or `epoch` or `None`.
- Invalid value for save_top_k={self.save_top_k}. Must be >= -
- Early stopping conditioned on metric `{self.monitor}` which
- Empty dict cannot be interpreted correct
- `mode` should be either of {self.SUPPORTED_MODES}
AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28).
Data as JSON: /api/errors/11c84a758f17f991.
Report an issue: GitHub.