PrefectHQ/fastmcp · error · AttributeError

module {__name__!r} has no attribute {name!r}

Error message

module {__name__!r} has no attribute {name!r}

What it means

fastmcp.server.auth also uses PEP 562 lazy attribute loading for its OAuth proxy classes; any name not in its handled set (AccessToken, OAuthProxy, OIDCProxy, etc.) hits the final `raise AttributeError(f"module {__name__!r} has no attribute {name!r}")`. It means the requested auth symbol doesn't exist at that path.

Source

Thrown at fastmcp_slim/fastmcp/server/auth/__init__.py:61

        return JWTVerifier
    if name == "StaticTokenVerifier":
        from .providers.jwt import StaticTokenVerifier

        return StaticTokenVerifier
    if name == "IdentityAssertion":
        from .identity_assertion import IdentityAssertion

        return IdentityAssertion
    if name == "OAuthProxy":
        from .oauth_proxy import OAuthProxy

        return OAuthProxy
    if name == "OIDCProxy":
        from .oidc_proxy import OIDCProxy

        return OIDCProxy
    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")


__all__ = [
    "AccessToken",
    "AuthCheck",
    "AuthContext",
    "AuthProvider",
    "DebugTokenVerifier",
    "IdentityAssertion",
    "JWTVerifier",
    "MultiAuth",
    "OAuthProvider",
    "OAuthProxy",
    "OIDCProxy",
    "RemoteAuthProvider",
    "StaticTokenVerifier",
    "TokenVerifier",
    "require_roles",

View on GitHub (pinned to 1f02114297)

Solutions

  1. Check the module's __all__ / docs for the exact exported names (case-sensitive: OAuthProxy, OIDCProxy).
  2. Import specialized providers from their submodules, e.g. fastmcp.server.auth.providers.jwt / bearer.
  3. If following an older example, update to current symbol names — auth class names changed across FastMCP versions.
  4. For dynamic selection, map config strings to imports explicitly instead of getattr on the package.

Example fix

// before
from fastmcp.server.auth import BearerAuthProvider  # not exported here

// after
from fastmcp.server.auth.providers.jwt import JWTVerifier  # current location
Defensive patterns

Strategy: validation

Validate before calling

import fastmcp.server.auth as auth
name = 'OAuthProxy'
if name not in auth.__all__:
    raise AttributeError(f'{name} not exported by fastmcp.server.auth; available: {auth.__all__}')

Try / catch

try:
    provider_cls = getattr(auth, config['auth_provider'])
except AttributeError as e:
    raise ValueError(f'unknown auth provider {config["auth_provider"]!r}') from e

Prevention

When it happens

Trigger: Execute `from fastmcp.server.auth import SomeAuth` or getattr(fastmcp.server.auth, name) with a name not matched by the __getattr__ branches — fallthrough at fastmcp_slim/fastmcp/server/auth/__init__.py:61.

Common situations: Typos like `OauthProxy` or `JWTVerifier` living in a different submodule; version changes moving/renaming auth providers; tutorials referencing symbols from fastmcp.server.auth.providers.* but imported from the package root; dynamic provider selection from config.

Related errors


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