Lightning-AI/pytorch-lightning · error · ValueError
`self.log({name}, {value})` was called, but nested dictionar
Error message
`self.log({name}, {value})` was called, but nested dictionaries cannot be logged What it means
__check_not_nested rejects dictionaries passed to self.log whose values contain other dicts. This is a self-imposed simplicity restriction in the Fabric logging path: logged dicts must be flat maps of scalar/tensor values.
Source
Thrown at src/lightning/pytorch/core/module.py:653
) -> None:
if logger is False:
# Passing `logger=False` with Fabric does not make much sense because there is no other destination to
# log to, but we support it in case the original code was written for Trainer use
return
if any(isinstance(v, dict) for v in dictionary.values()):
raise ValueError(f"`self.log_dict({dictionary})` was called, but nested dictionaries cannot be logged")
for name, value in dictionary.items():
apply_to_collection(value, object, self.__check_allowed, name, value, wrong_dtype=(numbers.Number, Tensor))
assert self._fabric is not None
self._fabric.log_dict(metrics=dictionary) # type: ignore[arg-type]
@staticmethod
def __check_not_nested(value: dict, name: str) -> None:
# self-imposed restriction. for simplicity
if any(isinstance(v, dict) for v in value.values()):
raise ValueError(f"`self.log({name}, {value})` was called, but nested dictionaries cannot be logged")
@staticmethod
def __check_allowed(v: Any, name: str, value: Any) -> None:
raise ValueError(f"`self.log({name}, {value})` was called, but `{type(v).__name__}` values cannot be logged")
def __to_tensor(self, value: Union[Tensor, numbers.Number], name: str) -> Tensor:
value = (
value.clone().detach()
if isinstance(value, Tensor)
else torch.tensor(value, device=self.device, dtype=_get_default_dtype())
)
if not torch.numel(value) == 1:
raise ValueError(
f"`self.log({name}, {value})` was called, but the tensor must have a single element."
f" You can try doing `self.log({name}, {value}.mean())`"
)
value = value.squeeze()
return valueView on GitHub (pinned to 9fed5c27d2)
Solutions
- Flatten nested keys with a separator before logging
- Use self.log_dict on the flattened dict
Example fix
# before
self.log('metrics', {'loss': {'total': l}})
# after
self.log('metrics/loss/total', l) Defensive patterns
Strategy: type-guard
Validate before calling
if any(isinstance(v, dict) for v in value.values()):
value = flatten(value) # reuse a flatten helper
self.log(name, value) Type guard
def is_not_nested(d) -> bool:
return not any(isinstance(v, dict) for v in d.values()) Prevention
- Never log dicts-of-dicts; flatten before logging
- Add a unit test asserting logged payloads are flat
When it happens
Trigger: self.log(name, {'a': {'b': 1}}) or any dict value containing a dict when running under Fabric logging.
Common situations: Logging grouped/nested experiment configs or hierarchical metric trees directly instead of flattening keys.
Related errors
- `self.log_dict({dictionary})` was called, but nested diction
- `setup_optimizers` requires at least one optimizer as input.
- `setup_dataloaders` requires at least one dataloader as inpu
- `self.log({name}, {value})` was called, but `{type(v).__name
- Device should be CPU, got {device} instead.
AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28).
Data as JSON: /api/errors/eb22c29e83daa43f.
Report an issue: GitHub.