{"record":{"id":"11c84a758f17f991","repo":"Lightning-AI/pytorch-lightning","slug":"mode-can-be-join-self-mode-dict-keys","errorCode":null,"errorMessage":"`mode` can be {', '.join(self.mode_dict.keys())}, got {self.mode}","messagePattern":"`mode` can be (.+?), got (.+?)","errorType":"validation","errorClass":"MisconfigurationException","httpStatus":null,"severity":"error","filePath":"src/lightning/pytorch/callbacks/early_stopping.py","lineNumber":146,"sourceCode":"        super().__init__()\n        self.monitor = monitor\n        self.min_delta = min_delta\n        self.patience = patience\n        self.verbose = verbose\n        self.mode = mode\n        self.strict = strict\n        self.check_finite = check_finite\n        self.stopping_threshold = stopping_threshold\n        self.divergence_threshold = divergence_threshold\n        self.wait_count = 0\n        self.stopped_epoch = 0\n        self.stopping_reason = EarlyStoppingReason.NOT_STOPPED\n        self.stopping_reason_message: Optional[str] = None\n        self._check_on_train_epoch_end = check_on_train_epoch_end\n        self.log_rank_zero_only = log_rank_zero_only\n\n        if self.mode not in self.mode_dict:\n            raise MisconfigurationException(f\"`mode` can be {', '.join(self.mode_dict.keys())}, got {self.mode}\")\n\n        self.min_delta *= 1 if self.monitor_op == torch.gt else -1\n        torch_inf = torch.tensor(torch.inf)\n        self.best_score = torch_inf if self.monitor_op == torch.lt else -torch_inf\n\n    @property\n    @override\n    def state_key(self) -> str:\n        return self._generate_state_key(monitor=self.monitor, mode=self.mode)\n\n    @override\n    def setup(self, trainer: \"pl.Trainer\", pl_module: \"pl.LightningModule\", stage: str) -> None:\n        if self._check_on_train_epoch_end is None:\n            # if the user runs validation multiple times per training epoch or multiple training epochs without\n            # validation, then we run after validation instead of on train epoch end\n            self._check_on_train_epoch_end = trainer.val_check_interval == 1.0 and trainer.check_val_every_n_epoch == 1\n\n    def _validate_condition_metric(self, logs: dict[str, Tensor]) -> bool:","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/pytorch/callbacks/early_stopping.py#L128-L164","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nEarlyStopping(monitor='val_loss', mode='minimum')\n// after\nEarlyStopping(monitor='val_loss', mode='min')","handlingStrategy":"validation","validationCode":"from lightning.pytorch.callbacks.early_stopping import EarlyStopping\nmode = 'min'  # from config\nassert mode in ('min', 'max'), f\"mode must be min/max, got {mode!r}\"","typeGuard":"def is_valid_es_mode(mode: str) -> bool:\n    return isinstance(mode, str) and mode in ('min', 'max')","tryCatchPattern":null,"preventionTips":["Validate mode against ('min','max') in config-loading code","Centralize callback construction in one factory with typed config (pydantic Literal['min','max'])"],"tags":["lightning","early-stopping","callback-config","invalid-argument"],"backgroundTag":"invalid-config-value","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}