PrefectHQ/fastmcp · error · ValueError
File {name!r} not found. Available: {available}
Error message
File {name!r} not found. Available: {available} What it means
FileUpload keeps uploaded files per session scope; reading a file whose name is not in the current session's store raises this ValueError listing the names that are available. It is a user-facing lookup failure, not a library bug.
Source
Thrown at fastmcp_slim/fastmcp/apps/file_upload.py:255
ctx: The current request context.
Override this method for custom persistence. The default
implementation reads from the current scope's in-memory store.
Text files are decoded from base64; binary files return a
truncated base64 preview.
Returns:
Dict with file metadata and ``content`` (text) or
``content_base64`` (binary preview).
Raises:
ValueError: If the file is not found.
"""
scope = self._get_scope_key(ctx)
session_files = self._store.get(scope, {})
if name not in session_files:
available = list(session_files.keys())
raise ValueError(f"File {name!r} not found. Available: {available}")
entry = session_files[name]
result: dict[str, Any] = {
"name": entry["name"],
"size": entry["size"],
"type": entry["type"],
"uploaded_at": entry["uploaded_at"],
}
is_text = entry["type"].startswith("text/") or any(
entry["name"].endswith(ext) for ext in _TEXT_EXTENSIONS
)
if is_text:
try:
result["content"] = base64.b64decode(entry["data"]).decode("utf-8")
except UnicodeDecodeError:
result["content_base64"] = entry["data"][:200] + "..."
else:
result["content_base64"] = entry["data"][:200] + "..."
return resultView on GitHub (pinned to 1f02114297)
Solutions
- Use one of the names listed in the error's `Available: [...]` list.
- Upload the file first in the same session, then read it by the exact uploaded name.
- If the store was reset by a restart, re-upload the file.
Example fix
// before read_file(name="report.pdf") # uploaded as "Report.PDF" // after read_file(name="Report.PDF") # exact name from upload response
Defensive patterns
Strategy: try-catch
Validate before calling
available = list_uploadable_files(ctx) # or track names returned by upload
if name not in available:
raise KeyError(f"{name!r} not uploaded in this session; available: {available}") Try / catch
try:
result = read_file(name=filename)
except ValueError as e:
if "not found" in str(e):
available = eval(str(e).split("Available:")[1].strip())
filename = available[0] # or prompt the user to pick Prevention
- Use the exact name returned by the upload response
- Do not assume files persist across server restarts or session scopes
- List available files before reading when unsure
- Keep uploads and reads within the same session
When it happens
Trigger: Calling the read/download tool with a `name` that was never uploaded in this session, or uploaded in a different session scope (different session key), or after the in-memory store was reset (server restart).
Common situations: Referring to a file by a different name than uploaded (client renames); cross-session access; server restarted losing the in-memory store; multiple users sharing a client with distinct session scopes.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Cannot resolve tool reference: {fn!r}
- Cannot determine tool name for {fn!r}
- File {f.get('name', '?')!r} exceeds max size ({_format_size(
- cache_ttl must be a positive integer, got {cache_ttl}
- ToolTransform has duplicate target name {target!r}: both {se
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/e0122a2313e5acba.
Report an issue: GitHub.