pytest-dev/pytest · error · OSError

could not create numbered dir with prefix

Error message

could not create numbered dir with prefix {prefix} in {root} after 10 tries

What it means

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.

Solutions

  1. Check and fix write permissions on the root/basetemp directory.
  2. Set a writable basetemp via --basetemp=/path/to/writable/dir.
  3. Free disk space if full.
  4. Avoid pointing pytest's tmp dir at a read-only or network mount under heavy concurrency.

Example fix

// before
pytest --basetemp=/readonly/run
// after
pytest --basetemp=/var/tmp/pytest-run
Defensive patterns

Strategy: validation

Validate before calling

import os
root = pathlib.Path(basetemp)
if not os.access(root, os.W_OK):
    raise RuntimeError(f'{root} is not writable')

Type guard

def _dir_writable(p) -> bool:
    import os
    return os.access(p, os.W_OK)

Try / catch

try:
    make_numbered_dir(root, prefix)
except OSError as e:
    # fall back to an alternative writable basetemp
    pass

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11). Data as JSON: /api/errors/75c0ab83f8a3d2d5. Report an issue: GitHub.

Appendix: source

Thrown at src/_pytest/pathlib.py:283

        pass


def make_numbered_dir(root: Path, prefix: str, mode: int = 0o700) -> Path:
    """Create a directory with an increased number as suffix for the given prefix."""
    for i in range(10):
        # try up to 10 times to create the directory
        max_existing = max(map(parse_num, find_suffixes(root, prefix)), default=-1)
        new_number = max_existing + 1
        new_path = root.joinpath(f"{prefix}{new_number}")
        try:
            new_path.mkdir(mode=mode)
        except Exception:
            pass
        else:
            _force_symlink(root, prefix + "current", new_path)
            return new_path
    else:
        raise OSError(
            "could not create numbered dir with prefix "
            f"{prefix} in {root} after 10 tries"
        )


def create_cleanup_lock(p: Path) -> Path:
    """Create a lock to prevent premature directory cleanup."""
    lock_path = get_lock_path(p)
    try:
        fd = os.open(str(lock_path), os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644)
    except FileExistsError as e:
        raise OSError(f"cannot create lockfile in {p}") from e
    else:
        pid = os.getpid()
        spid = str(pid).encode()
        os.write(fd, spid)
        os.close(fd)
        if not lock_path.is_file():

View on GitHub (pinned to 0d6fbdeffa)