Lightning-AI/pytorch-lightning · error · TypeError

outputs have to be of type torch.Tensor or Mapping, got {typ

Error message

outputs have to be of type torch.Tensor or Mapping, got {type(outputs).__qualname__}

What it means

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.

Source

Thrown at src/lightning/pytorch/callbacks/spike.py:27

from lightning.pytorch.callbacks.callback import Callback


class SpikeDetection(FabricSpikeDetection, Callback):
    @torch.no_grad()
    def on_train_batch_end(  # type: ignore
        self,
        trainer: "pl.Trainer",
        pl_module: "pl.LightningModule",
        outputs: Union[torch.Tensor, Mapping[str, torch.Tensor]],
        batch: Any,
        batch_idx: int,
    ) -> None:
        if isinstance(outputs, torch.Tensor):
            loss = outputs.detach()
        elif isinstance(outputs, Mapping):
            loss = outputs["loss"].detach()
        else:
            raise TypeError(f"outputs have to be of type torch.Tensor or Mapping, got {type(outputs).__qualname__}")

        if self.exclude_batches_path is None:
            self.exclude_batches_path = os.path.join(trainer.default_root_dir, "skip_batches.json")

        return FabricSpikeDetection.on_train_batch_end(self, trainer, loss, batch, batch_idx)  # type: ignore

View on GitHub (pinned to 9fed5c27d2)

Solutions

  1. Return the loss tensor or a dict containing 'loss' from training_step
  2. If returning a namedtuple/dataclass, convert it to a plain dict with a 'loss' entry
  3. Disable/remove the Spike callback if you don't need anomaly detection

Example fix

# before
def training_step(self, batch, batch_idx):
    loss, logits = self.step(batch)
    return loss, logits  # tuple -> TypeError
# after
def training_step(self, batch, batch_idx):
    loss, logits = self.step(batch)
    return {"loss": loss, "logits": logits}
Defensive patterns

Strategy: type-guard

Validate before calling

from collections.abc import Mapping
import torch

def outputs_ok(outputs) -> bool:
    return isinstance(outputs, torch.Tensor) or (isinstance(outputs, Mapping) and "loss" in outputs)

Type guard

from collections.abc import Mapping
import torch

def is_valid_outputs(outputs: object) -> bool:
    """Narrow outputs to Tensor | Mapping-with-loss for Spike-safe training_step returns."""
    return isinstance(outputs, torch.Tensor) or (
        isinstance(outputs, Mapping) and isinstance(outputs.get("loss"), torch.Tensor)
    )

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


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