PrefectHQ/fastmcp · error · ResourceError
Error reading file {self.path}
Error message
Error reading file {self.path} What it means
When FileResource.read() fails for any reason (file missing, permission denied, decode error, etc.), the original exception is wrapped in a ResourceError whose message names the path. The underlying cause is chained (raise ... from e), so inspect __cause__ to see the real OS-level error.
Source
Thrown at fastmcp_slim/fastmcp/resources/types.py:110
"""Set is_binary based on mime_type if not explicitly set."""
if is_binary:
return True
mime_type = info.data.get("mime_type", "text/plain")
return not mime_type.startswith("text/")
@override
async def read(self) -> ResourceResult:
"""Read the file content."""
try:
if self.is_binary:
content: str | bytes = await self._async_path.read_bytes()
else:
content = await self._async_path.read_text(encoding=self.encoding)
return ResourceResult(
contents=[ResourceContent(content=content, mime_type=self.mime_type)]
)
except Exception as e:
raise ResourceError(f"Error reading file {self.path}") from e
class HttpResource(Resource):
"""A resource that reads from an HTTP endpoint."""
url: str = Field(description="URL to fetch content from")
mime_type: str = Field(
default="application/json", description="MIME type of the resource content"
)
@override
async def read(self) -> ResourceResult:
"""Read the HTTP content."""
async with httpx2.AsyncClient() as client:
response = await client.get(self.url)
_ = response.raise_for_status()
return ResourceResult(
contents=[View on GitHub (pinned to 1f02114297)
Solutions
- Check the chained cause (e.g. try/except ResourceError as e: print(e.__cause__)) to see the OS error and fix it - create the file or fix permissions
- Set is_binary=True and an appropriate binary mime_type for non-text files
- Verify the path exists and is readable at startup: Path(path).exists() and os.access(path, os.R_OK)
- Wrap reads in try/except ResourceError and return a helpful message to the client
Example fix
// before
content = await file_resource.read() # ResourceError: Error reading file /data/x.csv
// after
try:
result = await file_resource.read()
except ResourceError as e:
logger.error(f"resource read failed: {e} (cause: {e.__cause__})")
raise Defensive patterns
Strategy: try-catch
Validate before calling
import os
from pathlib import Path
def assert_readable(p):
path = Path(p)
if not path.exists():
raise FileNotFoundError(path)
if not os.access(path, os.R_OK):
raise PermissionError(path) Type guard
def file_readable(p) -> bool:
import os
path = Path(p)
return path.is_file() and os.access(path, os.R_OK) Try / catch
try:
result = await file_resource.read()
except ResourceError as e:
logger.error("read failed for %s: %s", file_resource.path, e.__cause__)
raise Prevention
- Check existence/readability at startup or first access, not only at read time
- Set is_binary=True and a binary mime_type for non-UTF-8 files
- Log e.__cause__ - the wrapped OS error is what matters for diagnosis
- Re-register resources if the underlying files move
When it happens
Trigger: Calling read() (directly or via MCP resource read) on a FileResource whose path doesn't exist, isn't readable, was deleted after registration, or whose bytes don't decode with the configured encoding.
Common situations: File removed/moved after server start; running server as a user lacking read permission; encoding mismatch (binary file read as UTF-8 text); wrong is_binary flag for the content type.
Related errors
- Could not read CLI state: {path.name}
- Could not write CLI state: {path.name}
- Directory not found: {self.path}
- Not a directory: {self.path}
- Error listing directory {self.path}
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/f3401b77e4852465.
Report an issue: GitHub.