PrefectHQ/fastmcp · error · FileNotFoundError

Directory not found: {self.path}

Error message

Directory not found: {self.path}

What it means

DirectoryResource.list_files() raises FileNotFoundError when the resource's configured `path` does not exist on disk at the time the resource is read. FastMCP validates only that the path is absolute at construction; existence is checked lazily on each read, so a directory can vanish (or never have existed) after the resource is registered.

Source

Thrown at fastmcp_slim/fastmcp/resources/types.py:163

        default="application/json", description="MIME type of the resource content"
    )

    @property
    def _async_path(self) -> AsyncPath:
        return AsyncPath(self.path)

    @pydantic.field_validator("path")
    @classmethod
    def validate_absolute_path(cls, path: Path) -> Path:
        """Ensure path is absolute."""
        if not path.is_absolute():
            raise ValueError("Path must be absolute")
        return path

    async def list_files(self) -> list[Path]:
        """List files in the directory."""
        if not await self._async_path.exists():
            raise FileNotFoundError(f"Directory not found: {self.path}")
        if not await self._async_path.is_dir():
            raise NotADirectoryError(f"Not a directory: {self.path}")

        pattern = self.pattern or "*"

        glob_fn = self._async_path.rglob if self.recursive else self._async_path.glob
        try:
            return [Path(p) async for p in glob_fn(pattern) if await p.is_file()]
        except Exception as e:
            raise ResourceError(f"Error listing directory {self.path}") from e

    @override
    async def read(self) -> ResourceResult:
        """Read the directory listing."""
        try:
            files: list[Path] = await self.list_files()

            file_list = [str(f.relative_to(self.path)) for f in files]

View on GitHub (pinned to 1f02114297)

Solutions

  1. Create the directory at the configured path (mkdir -p) before serving/reading the resource.
  2. Verify the absolute path configured on DirectoryResource is correct for the runtime environment (print it or log it in list_files).
  3. Mount or copy the expected directory into containers/deployments; check volume mounts.
  4. Wrap reads and surface a clear message, or fail fast at startup with an explicit existence check.

Example fix

// before
resource = DirectoryResource(path=Path('/data/reports'), name='reports')
await resource.read()  # FileNotFoundError if /data/reports missing

// after
path = Path('/data/reports')
path.mkdir(parents=True, exist_ok=True)
resource = DirectoryResource(path=path, name='reports')
await resource.read()
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
path = Path('/data/reports')
if not path.is_dir():
    raise FileNotFoundError(f'Directory resource path missing: {path}')

Try / catch

try:
    result = await resource.read()
except FileNotFoundError as e:
    logger.error('directory missing: %s', e)

Prevention

When it happens

Trigger: Register a DirectoryResource with `path` pointing to a non-existent directory (e.g. fastmcp_slim/fastmcp/resources/types.py:163) and then call resource.read() (or have a client fetch the resource), which invokes list_files().

Common situations: Typo in the configured directory path; deploying to a container/host where the directory was never created or isn't mounted; directory deleted after server startup; using a relative-looking path that resolved to a wrong absolute location.

Related errors


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/f12525156c060c10. Report an issue: GitHub.