{"record":{"id":"6b7887f0dc7f6754","repo":"Lightning-AI/pytorch-lightning","slug":"epoch-should-be-an-int-greater-than-or-equal-to-0","errorCode":null,"errorMessage":"Epoch should be an int greater than or equal to 0. Got {list(scheduling.keys())}.","messagePattern":"Epoch should be an int greater than or equal to 0\\. Got (.+?)\\.","errorType":"validation","errorClass":"MisconfigurationException","httpStatus":null,"severity":"error","filePath":"src/lightning/pytorch/callbacks/gradient_accumulation_scheduler.py","lineNumber":74,"sourceCode":"\n        >>> from lightning.pytorch import Trainer\n        >>> from lightning.pytorch.callbacks import GradientAccumulationScheduler\n\n        # from epoch 5, it starts accumulating every 2 batches. Here we have 4 instead of 5\n        # because epoch (key) should be zero-indexed.\n        >>> accumulator = GradientAccumulationScheduler(scheduling={4: 2})\n        >>> trainer = Trainer(callbacks=[accumulator])\n\n    \"\"\"\n\n    def __init__(self, scheduling: dict[int, int]):\n        super().__init__()\n\n        if not scheduling:  # empty dict error\n            raise TypeError(\"Empty dict cannot be interpreted correct\")\n\n        if any(not isinstance(key, int) or key < 0 for key in scheduling):\n            raise MisconfigurationException(\n                f\"Epoch should be an int greater than or equal to 0. Got {list(scheduling.keys())}.\"\n            )\n\n        if any(not isinstance(value, int) or value < 1 for value in scheduling.values()):\n            raise MisconfigurationException(\n                f\"Accumulation factor should be an int greater than 0. Got {list(scheduling.values())}.\"\n            )\n\n        minimal_epoch = min(scheduling.keys())\n        if minimal_epoch < 0:\n            raise IndexError(f\"Epochs indexing from 1, epoch {minimal_epoch} cannot be interpreted correct\")\n        if minimal_epoch != 0:  # if user didn't define first epoch accumulation factor\n            scheduling.update({0: 1})\n\n        self.scheduling = scheduling\n        self.epochs = sorted(scheduling.keys())\n\n    def going_to_accumulate_grad_batches(self) -> bool:","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/pytorch/callbacks/gradient_accumulation_scheduler.py#L56-L92","documentation":"All keys of the `scheduling` dict must be ints >= 0 (epochs). Any non-int key (float, string) or negative int raises MisconfigurationException listing the offending keys. Validated in `__init__` at construction time.","triggerScenarios":"`GradientAccumulationScheduler({0.5: 4})`, `{'1': 8}`, or `{-1: 2}`. Common when the dict comes from JSON/YAML where keys are strings, or from division producing floats.","commonSituations":"Loading a schedule from JSON (keys always parse as strings); computing epochs with `total/2` yielding a float; negative epoch offsets from off-by-one math.","solutions":["Convert keys to int: `{int(k): v for k, v in schedule.items()}`","Fix epoch computation to produce non-negative integers","Check the reported key list in the message to spot float/string/negative entries"],"exampleFix":"# before\nschedule = json.loads('{\"0\": 8, \"5\": 2}')\nGradientAccumulationScheduler(schedule)\n# after\nschedule = {int(k): v for k, v in json.loads(raw).items()}\nGradientAccumulationScheduler(schedule)","handlingStrategy":"validation","validationCode":"if any(not isinstance(k, int) or isinstance(k, bool) or k < 0 for k in scheduling):\n    scheduling = {int(k): v for k, v in scheduling.items()}  # coerce from JSON/YAML strings\nassert all(isinstance(k, int) and k >= 0 for k in scheduling)","typeGuard":"def valid_epoch_keys(s: dict) -> bool:\n    return all(type(k) is int and k >= 0 for k in s)","tryCatchPattern":null,"preventionTips":["Coerce JSON/YAML keys with int() at load time","Use type-annotated config (pydantic dict[int,int]) so strings are rejected early"],"tags":["lightning","gradient-accumulation","invalid-key","type-validation"],"backgroundTag":"invalid-config-value","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}