Lightning-AI/pytorch-lightning · error · IsADirectoryError
The checkpoint path exists and is a directory: {path}
Error message
The checkpoint path exists and is a directory: {path} What it means
When saving a checkpoint with ModelParallelStrategy without distributed checkpointing (_save_distributed_checkpoint=False), the target path must be a file. If the resolved path already exists as a directory (and is not recognized as a sharded checkpoint being resumed), Lightning raises IsADirectoryError.
Source
Thrown at src/lightning/pytorch/strategies/model_parallel.py:313
@override
def load_optimizer_state_dict(self, checkpoint: Mapping[str, Any]) -> None:
# Override to do nothing, the strategy already loaded the states in `load_checkpoint()`
pass
@override
def save_checkpoint(
self, checkpoint: dict[str, Any], filepath: _PATH, storage_options: Optional[Any] = None
) -> None:
if storage_options is not None:
raise TypeError(
f"`{type(self).__name__}.save_checkpoint(..., storage_options=...)` is not supported because"
f" `{type(self).__name__}` does not use the `CheckpointIO`."
)
# broadcast the path from rank 0 to ensure all the checkpoints are saved to a common path
path = _resolve_path(self.broadcast(filepath))
if _is_checkpoint_dir(path) and not self._save_distributed_checkpoint and not _is_sharded_checkpoint(path):
raise IsADirectoryError(f"The checkpoint path exists and is a directory: {path}")
if self._save_distributed_checkpoint:
_prepare_directory_checkpoint(path)
converted_state = {"state_dict": checkpoint.pop("state_dict")}
converted_state.update({
f"optimizer_{idx}": optim_state
for idx, optim_state in enumerate(checkpoint.pop("optimizer_states", []))
})
_distributed_checkpoint_save(converted_state, path)
if self.global_rank == 0:
_atomic_save(checkpoint, _checkpoint_join(path, _METADATA_FILENAME))
else:
if _is_sharded_checkpoint(path):
_remove_checkpoint(path)
return super().save_checkpoint(checkpoint=checkpoint, filepath=path)
View on GitHub (pinned to 9fed5c27d2)
Solutions
- Pass a full file path, e.g. os.path.join(dirpath, 'last.ckpt')
- If the target really should be a sharded/distributed checkpoint directory, enable the strategy's distributed checkpoint option (_save_distributed_checkpoint=True)
- Remove or rename the conflicting directory if it was created by mistake
Example fix
# before strategy.save_checkpoint(ckpt, "checkpoints/run1/") # after strategy.save_checkpoint(ckpt, "checkpoints/run1/last.ckpt")
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
p = Path(filepath)
assert not (p.exists() and p.is_dir()), f"{filepath} is a directory; pass a file path like {p}/last.ckpt" Prevention
- Always build checkpoint paths as dirpath + filename
- Enable distributed checkpointing if directory checkpoints are intended
When it happens
Trigger: Calling save_checkpoint with a path that is an existing directory (e.g. passing a run dir like 'checkpoints/run1/' rather than 'checkpoints/run1/last.ckpt'), while not using distributed checkpoints and the dir not being a sharded checkpoint.
Common situations: Passing ModelCheckpoint.dirpath instead of a filename; reusing a resume path that points at a DCP directory while the strategy is in full-checkpoint mode.
Related errors
- {default_message}. It looks like you passed the path to a su
- {default_message}. It looks like you passed the path to a fi
- The provided path is not a valid DeepSpeed checkpoint: {path
- Could not find a distributed model in the provided checkpoin
- Found multiple distributed models in the given state. Loadin
AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28).
Data as JSON: /api/errors/aae2711626dd4e86.
Report an issue: GitHub.