aio-libs/aiohttp · error · ValueError
'{directory}' does not exist
Error message
'{directory}' does not exist What it means
Raised as ValueError by StaticResource.__init__ when Path(directory).resolve(strict=True) raises FileNotFoundError — i.e. the configured static directory does not exist on disk. The static resource needs a real directory to serve files from at setup time, so a missing path is rejected immediately rather than 404-ing every request.
Source
Thrown at aiohttp/web_urldispatcher.py:519
VERSION_KEY = "v"
def __init__(
self,
prefix: str,
directory: PathLike,
*,
name: str | None = None,
expect_handler: _ExpectHandler | None = None,
chunk_size: int = DEFAULT_CHUNK_SIZE,
show_index: bool = False,
break_symlink_sandbox: bool = False,
append_version: bool = False,
) -> None:
super().__init__(prefix, name=name)
try:
directory = Path(directory).expanduser().resolve(strict=True)
except FileNotFoundError as error:
raise ValueError(f"'{directory}' does not exist") from error
if not directory.is_dir():
raise ValueError(f"'{directory}' is not a directory")
self._directory = directory
self._show_index = show_index
self._chunk_size = chunk_size
self._break_symlink_sandbox = break_symlink_sandbox
self._expect_handler = expect_handler
self._append_version = append_version
self._routes = {
"GET": ResourceRoute(
"GET", self._handle, self, expect_handler=expect_handler
),
"HEAD": ResourceRoute(
"HEAD", self._handle, self, expect_handler=expect_handler
),
}
self._allowed_methods = set(self._routes)View on GitHub (pinned to c0ef574e29)
Solutions
- Verify the directory exists: check with Path(directory).resolve() before add_static.
- Use an absolute path derived from __file__: Path(__file__).parent / 'static'.
- Ensure build/copy steps (npm run build, COPY in Dockerfile) run before server startup.
- In containers, confirm the directory is present at the expected absolute path.
Example fix
# before
app.router.add_static('/static', '/var/www/assets') # missing
# after
from pathlib import Path
static_dir = Path(__file__).parent / 'assets'
app.router.add_static('/static', static_dir) Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def resolve_static_dir(directory):
p = Path(directory).expanduser()
if not p.exists():
raise FileNotFoundError(f"static directory does not exist: {p}")
return p.resolve() Type guard
from pathlib import Path
def directory_exists(directory) -> bool:
return Path(directory).expanduser().exists() Try / catch
try:
app.router.add_static('/static', directory)
except ValueError as e:
if 'does not exist' in str(e):
raise SystemExit(f"Static dir missing: {e}") from e
raise Prevention
- Derive static paths from __file__ (Path(__file__).parent / 'static').
- In Docker, COPY assets before CMD and verify the path exists.
- Add a startup check that all static dirs exist before binding routes.
When it happens
Trigger: Calling app.router.add_static('/static', '/wrong/path') or web.static('/s', './missing') where the directory does not exist. Relative paths resolved against an unexpected working directory also trigger it.
Common situations: Deploying with a different working directory than dev; build step that creates the assets dir not yet run; typo in the path; containerized app where the static dir isn't copied into the image; path from config pointing to a host path not mounted.
Related errors
- '{directory}' is not a directory
- {method} is not allowed HTTP method
- Invalid path '{path}'['{part}']
- Bad pattern '{pattern}': {exc}
- OPTIONS route was set already
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/6294cb0a2f5e6912.json.
Report an issue: GitHub.