{"record":{"id":"3c942f19d3df5a88","repo":"apache/beam","slug":"err-re-raised-oserror-from-os-makedirs","errorCode":null,"errorMessage":"err (re-raised OSError from os.makedirs)","messagePattern":"err \\(re-raised OSError from os\\.makedirs\\)","errorType":"exception","errorClass":"IOError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/localfilesystem.py","lineNumber":81,"sourceCode":"      path: path as a string\n    Returns:\n      a pair of path components as strings.\n    \"\"\"\n    return os.path.split(os.path.abspath(path))\n\n  def mkdirs(self, path):\n    \"\"\"Recursively create directories for the provided path.\n\n    Args:\n      path: string path of the directory structure that should be created\n\n    Raises:\n      IOError: if leaf directory already exists.\n    \"\"\"\n    try:\n      os.makedirs(path)\n    except OSError as err:\n      raise IOError(err)\n\n  def has_dirs(self):\n    \"\"\"Whether this FileSystem supports directories.\"\"\"\n    return True\n\n  def _url_dirname(self, url_or_path):\n    \"\"\"Pass through to os.path.dirname.\n\n    This version uses os.path instead of posixpath to be compatible with the\n    host OS.\n\n    Args:\n      url_or_path: A string in the form of /some/path.\n    \"\"\"\n    return os.path.dirname(url_or_path)\n\n  def _list(self, dir_or_prefix):\n    \"\"\"List files in a location.","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/localfilesystem.py#L63-L99","documentation":"LocalFileSystem.mkdirs wraps os.makedirs and converts any OSError (e.g. the leaf directory already exists, or a permission problem) into a plain IOError with the original error as its argument. It is the local implementation of the Beam FileSystem directory-creation contract, which documents IOError as the failure mode.","triggerScenarios":"Calling filesystem.mkdirs(path) where the leaf directory already exists (FileExistsError), a parent component is a file (NotADirectoryError), or the process lacks write permission on the parent (PermissionError). Any of these OS-level failures surface as IOError(err).","commonSituations":"Racing workers both creating the same temp/staging directory; writing to a read-only mount or a path owned by another user; accidentally passing a file path instead of a directory path.","solutions":["Check os.path.exists(path) and skip mkdirs if the directory is already present, or wrap the call in try/except IOError and ignore FileExistsError cases.","Verify the process has write permission on the parent directory, or run with appropriate credentials/ownership.","Make sure the path passed is a directory path, not an existing file path.","Prefer beam.io.filesystems.FileSystems.mkdirs for URL-based paths so the correct filesystem implementation handles the path."],"exampleFix":"// before\nfs.mkdirs(path)  # crashes if leaf dir exists\n// after\nimport os\nif not os.path.exists(path):\n    fs.mkdirs(path)","handlingStrategy":"try-catch","validationCode":"import os\nif not os.path.exists(path):\n    os.makedirs(path, exist_ok=True)  # or fs.mkdirs(path)","typeGuard":null,"tryCatchPattern":"try:\n    fs.mkdirs(path)\nexcept IOError as e:\n    if not os.path.isdir(path):\n        raise  # ignore benign already-exists; surface real errors","preventionTips":["Use exist_ok semantics: check os.path.isdir before or swallow the already-exists case","Ensure write permission on parent directories before running the pipeline","Do not pass a file path where a directory is expected"],"tags":["python","apache-beam","filesystem","mkdir","ioerror"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}