{"record":{"id":"cf8d9155569b1913","repo":"Lightning-AI/pytorch-lightning","slug":"missing-folder-os-path-dirname-config-yaml","errorCode":null,"errorMessage":"Missing folder: {os.path.dirname(config_yaml)}.","messagePattern":"Missing folder: (.+?)\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/lightning/pytorch/core/saving.py","lineNumber":343,"sourceCode":"\n        with contextlib.suppress(UnsupportedValueType, ValidationError):\n            # OmegaConf containers are mapping-like but not `dict` subclasses\n            return cast(\"dict[str, Any]\", OmegaConf.create(hparams))\n    return hparams\n\n\ndef save_hparams_to_yaml(config_yaml: _PATH, hparams: Union[dict, Namespace], use_omegaconf: bool = True) -> None:\n    \"\"\"\n    Args:\n        config_yaml: path to new YAML file\n        hparams: parameters to be saved\n        use_omegaconf: If omegaconf is available and ``use_omegaconf=True``,\n            the hparams will be converted to ``DictConfig`` if possible.\n\n    \"\"\"\n    fs = get_filesystem(config_yaml)\n    if not _is_dir(fs, os.path.dirname(config_yaml)):\n        raise RuntimeError(f\"Missing folder: {os.path.dirname(config_yaml)}.\")\n\n    # convert Namespace or AD to dict\n    if isinstance(hparams, Namespace):\n        hparams = vars(hparams)\n    elif isinstance(hparams, AttributeDict):\n        hparams = dict(hparams)\n\n    # saving with OmegaConf objects\n    if _OMEGACONF_AVAILABLE and use_omegaconf:\n        from omegaconf import OmegaConf\n        from omegaconf.dictconfig import DictConfig\n        from omegaconf.errors import UnsupportedValueType, ValidationError\n\n        # deepcopy: hparams from user shouldn't be resolved\n        hparams = deepcopy(hparams)\n        hparams = apply_to_collection(hparams, DictConfig, OmegaConf.to_container, resolve=True)\n        with fs.open(config_yaml, \"w\", encoding=\"utf-8\") as fp:\n            try:","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/pytorch/core/saving.py#L325-L361","documentation":"Same guard as the CSV writer but for save_hparams_to_yaml: the parent directory of config_yaml must exist on the fsspec filesystem or a RuntimeError is raised. Called from LightningModule.save and logger hyperparameter logging, so it frequently surfaces indirectly.","triggerScenarios":"trainer.logger.log_hyperparams / model.save writing a hparams.yaml into a folder that was never created; direct calls to save_hparams_to_yaml with a bad parent path.","commonSituations":"Custom save dirs (save_dir passed to loggers), fsspec remote targets, or code that assumed Lightning creates the folder (it does in most flows — the error usually means a custom path bypassed that).","solutions":["Create the parent directory before saving: Path(config_yaml).parent.mkdir(parents=True, exist_ok=True)","Verify save_dir / logger save path is correct and accessible","For remote URIs, check credentials and that the bucket/prefix exists"],"exampleFix":"// before\nsave_hparams_to_yaml(\"runs/abc/hparams.yaml\", hparams)  # runs/abc missing\n// after\nfrom pathlib import Path\nPath(\"runs/abc\").mkdir(parents=True, exist_ok=True)\nsave_hparams_to_yaml(\"runs/abc/hparams.yaml\", hparams)","handlingStrategy":"validation","validationCode":"from pathlib import Path\nPath(config_yaml).parent.mkdir(parents=True, exist_ok=True)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Centralize 'ensure dir exists' logic before any save","For remote fsspec paths, verify bucket/prefix reachability before training starts"],"tags":["lightning","hparams","yaml","missing-directory","fsspec"],"backgroundTag":"output-directory-missing","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}