{"record":{"id":"991054c27f0e5a78","repo":"goharbor/harbor","slug":"path-exists-and-the-type-is-regular-file","errorCode":null,"errorMessage":"Path exists and the type is regular file","messagePattern":"Path exists and the type is regular file","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"make/photon/prepare/utils/misc.py","lineNumber":68,"sourceCode":"        if storage_provider_config == \"\":\n            raise Exception(\n                \"Error: no provider configurations are provided for provider %s\" % storage_provider_name)\n\ndef validate_crt_subj(dirty_subj):\n    subj_list = [item for item in dirty_subj.strip().split(\"/\") \\\n        if len(item.split(\"=\")) == 2 and len(item.split(\"=\")[1]) > 0]\n    return \"/\" + \"/\".join(subj_list)\n\n\ndef generate_random_string(length):\n    return ''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(length))\n\n\ndef prepare_dir(root: str, *args, **kwargs) -> str:\n    gid, uid = kwargs.get('gid'), kwargs.get('uid')\n    absolute_path = Path(os.path.join(root, *args))\n    if absolute_path.is_file():\n        raise Exception('Path exists and the type is regular file')\n    mode = kwargs.get('mode') or 0o755\n\n    # we need make sure this dir has the right permission\n    if not absolute_path.exists():\n        absolute_path.mkdir(mode=mode, parents=True)\n    elif not check_permission(absolute_path, mode=mode):\n         absolute_path.chmod(mode)\n\n    # if uid or gid not None, then change the ownership of this dir\n    if not(gid is None and uid is None):\n        dir_uid, dir_gid = absolute_path.stat().st_uid, absolute_path.stat().st_gid\n        if uid is None:\n            uid = dir_uid\n        if gid is None:\n            gid = dir_gid\n        # We decide to recursively chown only if the dir is not owned by correct user\n        # to save time if the dir is extremely large\n        if not check_permission(absolute_path, uid, gid):","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/goharbor/harbor/blob/7b2fd08cc568955cca339afeefab27372840d936/make/photon/prepare/utils/misc.py#L50-L86","documentation":"Thrown by prepare_dir() in make/photon/prepare/utils/misc.py when the directory it is asked to create (e.g. <data_volume>/registry, /etc/registry config dirs inside the prepare container) already exists but is a regular file (absolute_path.is_file()). Rather than overwrite or fail halfway, prepare refuses and aborts, protecting whatever content the file holds.","triggerScenarios":"A regular file occupies the exact target path before install/prepare runs - e.g. someone created /data/registry as a file, a bind mount mounted a single file where a directory is expected, or leftover artifacts from previous experiments sit in the data_volume layout.","commonSituations":"Reusing a data_volume that previously held unrelated files; docker bind mounts created from single-file host paths; operators 'reserving' paths with touch; restoring partial backups where directories became files.","solutions":["Identify the offending file: the prepare log names the path being prepared when it aborts - inspect it (file <path>, cat) for valuable content","Move it aside or delete it: mv <path> <path>.bak","Ensure the parent data_volume is a real directory and mounts are directory mounts","Re-run ./install.sh - prepare_dir will now mkdir and set ownership/permissions"],"exampleFix":"# on the Harbor host (before)\n$ ls -l /data/registry\n-rw-r--r-- 1 root root 0 Jan  1 00:00 /data/registry   # a file!\n\n# after\n$ mv /data/registry /data/registry.bak\n$ ls -ld /data/registry\nmkdir happens on next ./install.sh","handlingStrategy":"type-guard","validationCode":"from pathlib import Path\n# before calling prepare_dir(root, *args):\ntarget = Path(root).joinpath(*args)\nif target.exists() and target.is_file():\n    raise SystemExit('%s exists and is a regular file - move it before prepare' % target)","typeGuard":"def is_clear_dir_path(p: str) -> bool:\n    \"\"\"True when p is a directory or does not exist (safe for prepare_dir).\"\"\"\n    path = Path(p)\n    return not path.exists() or path.is_dir()","tryCatchPattern":null,"preventionTips":["Keep data_volume clean - only Harbor-managed subdirectories should live there","Never bind-mount single files over Harbor directory paths","Check ls -ld <data_volume>/* after failed installs to spot file-vs-dir clashes"],"tags":["harbor","file-system","installation","data-volume"],"backgroundTag":null,"analyzedSha":"7b2fd08cc568955cca339afeefab27372840d936","analyzedAt":"2026-08-16T00:00:10.961Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}