{"record":{"id":"75c0ab83f8a3d2d5","repo":"pytest-dev/pytest","slug":"could-not-create-numbered-dir-with-prefix-prefix","errorCode":null,"errorMessage":"could not create numbered dir with prefix {prefix} in {root} after 10 tries","messagePattern":"could not create numbered dir with prefix (.+?) in (.+?) after 10 tries","errorType":"exception","errorClass":"OSError","httpStatus":null,"severity":"error","filePath":"src/_pytest/pathlib.py","lineNumber":283,"sourceCode":"        pass\n\n\ndef make_numbered_dir(root: Path, prefix: str, mode: int = 0o700) -> Path:\n    \"\"\"Create a directory with an increased number as suffix for the given prefix.\"\"\"\n    for i in range(10):\n        # try up to 10 times to create the directory\n        max_existing = max(map(parse_num, find_suffixes(root, prefix)), default=-1)\n        new_number = max_existing + 1\n        new_path = root.joinpath(f\"{prefix}{new_number}\")\n        try:\n            new_path.mkdir(mode=mode)\n        except Exception:\n            pass\n        else:\n            _force_symlink(root, prefix + \"current\", new_path)\n            return new_path\n    else:\n        raise OSError(\n            \"could not create numbered dir with prefix \"\n            f\"{prefix} in {root} after 10 tries\"\n        )\n\n\ndef create_cleanup_lock(p: Path) -> Path:\n    \"\"\"Create a lock to prevent premature directory cleanup.\"\"\"\n    lock_path = get_lock_path(p)\n    try:\n        fd = os.open(str(lock_path), os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644)\n    except FileExistsError as e:\n        raise OSError(f\"cannot create lockfile in {p}\") from e\n    else:\n        pid = os.getpid()\n        spid = str(pid).encode()\n        os.write(fd, spid)\n        os.close(fd)\n        if not lock_path.is_file():","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/pytest-dev/pytest/blob/0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc/src/_pytest/pathlib.py#L265-L301","documentation":"Raised by make_numbered_dir after 10 failed attempts to create a numbered directory under root with the given prefix. Each iteration (lines 270-281) computes the next suffix number and tries mkdir; on success it symlinks to 'current' and returns. If all 10 iterations raise (e.g. permission errors, race conditions, full disk), the for/else clause raises OSError at line 283. This backs pytest's tmp_path factory and cache dir layout.","triggerScenarios":"root directory is not writable (permissions); root is on a read-only filesystem; concurrent pytest processes racing on the same prefix causing symlink/mkdir collisions; disk full; root deleted out from under the run.","commonSituations":"Running pytest as a user without write access to the tmp/basetemp dir; container with read-only mounted volume for the cache; NFS or network filesystem race conditions; /tmp full in CI.","solutions":["Check and fix write permissions on the root/basetemp directory.","Set a writable basetemp via --basetemp=/path/to/writable/dir.","Free disk space if full.","Avoid pointing pytest's tmp dir at a read-only or network mount under heavy concurrency."],"exampleFix":"// before\npytest --basetemp=/readonly/run\n// after\npytest --basetemp=/var/tmp/pytest-run","handlingStrategy":"validation","validationCode":"import os\nroot = pathlib.Path(basetemp)\nif not os.access(root, os.W_OK):\n    raise RuntimeError(f'{root} is not writable')","typeGuard":"def _dir_writable(p) -> bool:\n    import os\n    return os.access(p, os.W_OK)","tryCatchPattern":"try:\n    make_numbered_dir(root, prefix)\nexcept OSError as e:\n    # fall back to an alternative writable basetemp\n    pass","preventionTips":["Use a writable --basetemp on local disk.","Avoid read-only or shared network mounts for tmp dirs."],"tags":["pytest","pathlib","oserror","filesystem","permissions"],"backgroundTag":null,"analyzedSha":"0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc","analyzedAt":"2026-08-11T20:52:36.969Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}