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 result

View on GitHub (pinned to 1f02114297)

Solutions

  1. Use one of the names listed in the error's `Available: [...]` list.
  2. Upload the file first in the same session, then read it by the exact uploaded name.
  3. 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

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


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