{"record":{"id":"bb49a141265f6867","repo":"Lightning-AI/pytorch-lightning","slug":"outputs-have-to-be-of-type-torch-tensor-or-mapping","errorCode":null,"errorMessage":"outputs have to be of type torch.Tensor or Mapping, got {type(outputs).__qualname__}","messagePattern":"outputs have to be of type torch\\.Tensor or Mapping, got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/lightning/pytorch/callbacks/spike.py","lineNumber":27,"sourceCode":"from lightning.pytorch.callbacks.callback import Callback\n\n\nclass SpikeDetection(FabricSpikeDetection, Callback):\n    @torch.no_grad()\n    def on_train_batch_end(  # type: ignore\n        self,\n        trainer: \"pl.Trainer\",\n        pl_module: \"pl.LightningModule\",\n        outputs: Union[torch.Tensor, Mapping[str, torch.Tensor]],\n        batch: Any,\n        batch_idx: int,\n    ) -> None:\n        if isinstance(outputs, torch.Tensor):\n            loss = outputs.detach()\n        elif isinstance(outputs, Mapping):\n            loss = outputs[\"loss\"].detach()\n        else:\n            raise TypeError(f\"outputs have to be of type torch.Tensor or Mapping, got {type(outputs).__qualname__}\")\n\n        if self.exclude_batches_path is None:\n            self.exclude_batches_path = os.path.join(trainer.default_root_dir, \"skip_batches.json\")\n\n        return FabricSpikeDetection.on_train_batch_end(self, trainer, loss, batch, batch_idx)  # type: ignore\n","sourceCodeStart":9,"sourceCodeEnd":33,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/pytorch/callbacks/spike.py#L9-L33","documentation":"The Spike detection callback extracts the training loss from the outputs of training_step at on_train_batch_end. It only knows how to read a torch.Tensor (the loss itself) or a Mapping (dict) containing a 'loss' key; any other return type (e.g. a dataclass, namedtuple, list, or tuple) triggers this TypeError.","triggerScenarios":"training_step returns something other than a Tensor or a Mapping (dict-like) while the Spike callback is enabled. Note: a namedtuple/dataclass return, or returning a list of losses, raises this. Also raised if outputs is a Mapping without a 'loss' key (KeyError variant behavior aside, type check fails first for non-mappings).","commonSituations":"Users returning custom result objects or plain tuples from training_step; using LightningModule subclasses migrated from older APIs that returned (loss, dict) tuples; using the experimental spike detection callback with unconventional modules.","solutions":["Return the loss tensor or a dict containing 'loss' from training_step","If returning a namedtuple/dataclass, convert it to a plain dict with a 'loss' entry","Disable/remove the Spike callback if you don't need anomaly detection"],"exampleFix":"# before\ndef training_step(self, batch, batch_idx):\n    loss, logits = self.step(batch)\n    return loss, logits  # tuple -> TypeError\n# after\ndef training_step(self, batch, batch_idx):\n    loss, logits = self.step(batch)\n    return {\"loss\": loss, \"logits\": logits}","handlingStrategy":"type-guard","validationCode":"from collections.abc import Mapping\nimport torch\n\ndef outputs_ok(outputs) -> bool:\n    return isinstance(outputs, torch.Tensor) or (isinstance(outputs, Mapping) and \"loss\" in outputs)","typeGuard":"from collections.abc import Mapping\nimport torch\n\ndef is_valid_outputs(outputs: object) -> bool:\n    \"\"\"Narrow outputs to Tensor | Mapping-with-loss for Spike-safe training_step returns.\"\"\"\n    return isinstance(outputs, torch.Tensor) or (\n        isinstance(outputs, Mapping) and isinstance(outputs.get(\"loss\"), torch.Tensor)\n    )","tryCatchPattern":null,"preventionTips":["Always return {'loss': loss, ...} from training_step","Avoid namedtuples/dataclasses as training_step return values","Unit-test training_step output shape when using anomaly-detection callbacks"],"tags":["spike-detection","training-step","typeerror","callback"],"backgroundTag":"callback-output-type-mismatch","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}