pypa/pip · error · OSError
"os.mkdir" not supported on this platform.
Error message
"os.mkdir" not supported on this platform.
What it means
Raised as OSError from _bypass_ensure_directory when the global WRITE_SUPPORT flag is falsy on the current platform. WRITE_SUPPORT is set to None on environments where os.mkdir is unavailable (notably Google App Engine standard), so the sandbox-bypassing directory creation helper refuses to run.
Source
Thrown at src/pip/_vendor/pkg_resources/__init__.py:3510
types = _always_object(inspect.getmro(getattr(ob, '__class__', type(ob))))
for t in types:
if t in registry:
return registry[t]
# _find_adapter would previously return None, and immediately be called.
# So we're raising a TypeError to keep backward compatibility if anyone depended on that behaviour.
raise TypeError(f"Could not find adapter for {registry} and {ob}")
def ensure_directory(path: StrOrBytesPath):
"""Ensure that the parent directory of `path` exists"""
dirname = os.path.dirname(path)
os.makedirs(dirname, exist_ok=True)
def _bypass_ensure_directory(path):
"""Sandbox-bypassing version of ensure_directory()"""
if not WRITE_SUPPORT:
raise OSError('"os.mkdir" not supported on this platform.')
dirname, filename = split(path)
if dirname and filename and not isdir(dirname):
_bypass_ensure_directory(dirname)
try:
mkdir(dirname, 0o755)
except FileExistsError:
pass
def split_sections(s: _NestedStr) -> Iterator[tuple[str | None, list[str]]]:
"""Split a string or iterable thereof into (section, content) pairs
Each ``section`` is a stripped version of the section header ("[section]")
and each ``content`` is a list of stripped lines excluding blank lines and
comment-only lines. If there are any such lines before the first section
header, they're returned in a first ``section`` of ``None``.
"""
section = NoneView on GitHub (pinned to d7d0d0a394)
Solutions
- Move off the restricted platform/runtime (e.g. GAE standard -> a runtime with full filesystem access) if you need directory creation.
- Pre-create the target directories out-of-band so _bypass_ensure_directory finds them and skips mkdir.
- Avoid the code path that triggers script/cache writing, or pin to a setuptools/pkg_resources version compatible with your sandbox.
Example fix
# before
# running on GAE standard -> OSError: "os.mkdir" not supported
# after
import os
os.makedirs('/tmp/myapp/cache', exist_ok=True) # pre-create outside sandbox
# configure pkg_resources to use this writable dir as cache Defensive patterns
Strategy: type-guard
Validate before calling
from pip._vendor.pkg_resources import WRITE_SUPPORT
if WRITE_SUPPORT is None:
raise RuntimeError('mkdir unavailable on this platform; pre-create dirs')
_bypass_ensure_directory(path) Type guard
def can_write() -> bool:
from pip._vendor.pkg_resources import WRITE_SUPPORT
return WRITE_SUPPORT is not None Try / catch
try:
_bypass_ensure_directory(path)
except OSError as e:
if 'os.mkdir' not in str(e):
raise
# pre-create directory out of band Prevention
- Avoid restricted runtimes (GAE standard) for code that writes via pkg_resources.
- Pre-create target directories in deployment scripts.
When it happens
Trigger: Running pkg_resources code that calls _bypass_ensure_directory (used for creating parent directories of scripts/cache) on a platform where os.mkdir is not available, e.g. GAE standard sandbox or a locked-down runtime that strips os.mkdir.
Common situations: Deploying an app that imports pkg_resources on Google App Engine, or running in a restricted sandbox that deletes os.mkdir; the helper is invoked when installing/writing scripts or metadata.
Related errors
- "os.rename" and "os.unlink" are not supported on this platfo
- Invalid group name
- Duplicate entry point
- Entry points must be listed in groups
- Duplicate group name
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/7fc0eb6a23dd8a86.json.
Report an issue: GitHub.