PrefectHQ/fastmcp · error · ValueError

Either name or uri must be provided

Error message

Either name or uri must be provided

What it means

Resource.set_default_name derives the resource name from its URI when no explicit name was given. If neither name nor uri is set, there is nothing to derive from and it raises this ValueError. It is a configuration-completeness check ensuring every resource has an MCP-visible identity.

Source

Thrown at fastmcp_slim/fastmcp/resources/base.py:410

        )

    @field_validator("mime_type", mode="before")
    @classmethod
    def set_default_mime_type(cls, mime_type: str | None) -> str:
        """Set default MIME type if not provided."""
        if mime_type:
            return mime_type
        return "text/plain"

    @model_validator(mode="after")
    def set_default_name(self) -> Self:
        """Set default name from URI if not provided."""
        if self.name:
            pass
        elif self.uri:
            self.name = str(self.uri)
        else:
            raise ValueError("Either name or uri must be provided")
        return self

    async def read(
        self,
    ) -> str | bytes | ResourceResult:
        """Read the resource content.

        Subclasses implement this to return resource data. Supported return types:
            - str: Text content
            - bytes: Binary content
            - ResourceResult: Full control over contents and result-level meta
        """
        raise NotImplementedError("Subclasses must implement read()")

    def convert_result(self, raw_value: Any) -> ResourceResult:
        """Convert a raw result to ResourceResult.

        This is used in two contexts:

View on GitHub (pinned to 1f02114297)

Solutions

  1. Pass a uri when constructing the Resource (e.g. Resource(uri='file:///data', ...) or via FunctionResource)
  2. Or pass an explicit name= so derivation is unnecessary
  3. Check for empty-string name values, which are falsy and don't count

Example fix

// before
res = Resource(fn=read_fn)
res.set_default_name()  # ValueError
// after
res = Resource(fn=read_fn, uri="data://config")
res.set_default_name()  # name becomes "data://config"
Defensive patterns

Strategy: validation

Validate before calling

def ensure_identity(name, uri):
    if not name and not uri:
        raise ValueError("Provide name or uri before set_default_name()")

Type guard

def has_identity(res) -> bool:
    return bool(getattr(res, "name", None)) or bool(getattr(res, "uri", None))

Try / catch

try:
    res.set_default_name()
except ValueError:
    res.name = res.uri = "data://fallback"
    res.set_default_name()

Prevention

When it happens

Trigger: Calling set_default_name() on a Resource constructed with neither name= nor uri= (or with empty-string name and no uri).

Common situations: Building resources programmatically and forgetting to pass uri; name accidentally set to "" which is falsy so the elif falls through to uri, which is also unset.

Related errors


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