PrefectHQ/fastmcp · error · ResourceError

Error reading directory {self.path}

Error message

Error reading directory {self.path}

What it means

DirectoryResource.read() is the public entry point for a directory listing; it catches every exception from listing and formatting (including FileNotFoundError, NotADirectoryError, and ResourceError from list_files) and re-raises it as a ResourceError reading 'Error reading directory {path}', preserving the cause. Clients of the MCP resource therefore always see ResourceError, not the underlying OS error.

Source

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

        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]

            content = json.dumps({"files": file_list}, indent=2)
            return ResourceResult(
                contents=[ResourceContent(content=content, mime_type=self.mime_type)]
            )
        except Exception as e:
            raise ResourceError(f"Error reading directory {self.path}") from e

View on GitHub (pinned to 1f02114297)

Solutions

  1. Catch ResourceError and inspect `__cause__` to identify the root failure (missing dir, permissions, etc.).
  2. Ensure the directory exists and is readable before/at server startup (mkdir + permission check).
  3. Verify the path is a directory and use symlinks carefully so results stay under `path` for relative_to().
  4. Add health/startup checks that call read() once so misconfiguration surfaces at boot.

Example fix

// before
await client.read_resource('dir://reports')  # ResourceError at runtime

// after
# at startup
path = Path('/data/reports')
assert path.is_dir(), f"directory resource path invalid: {path}"
Defensive patterns

Strategy: try-catch

Validate before calling

from pathlib import Path
path = Path('/data/reports')
assert path.is_dir() and os.access(path, os.R_OK), f'invalid directory resource: {path}'

Try / catch

try:
    result = await client.read_resource('dir://reports')
except ResourceError as e:
    logger.error('directory read failed: %s (cause: %r)', e, e.__cause__)

Prevention

When it happens

Trigger: Any client read of a DirectoryResource whose path is missing, is not a directory, is unreadable, or whose listing/formatting (relative_to/JSON serialization) fails — see the except at fastmcp_slim/fastmcp/resources/types.py:188.

Common situations: LLM clients fetch a directory resource in production where the mount is absent or permission-restricted; relative path components appear in listing (f.relative_to failing after symlinks escape the base); environment differences between dev and deploy.

Related errors


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