{"record":{"id":"1a9b0e15dba7ead0","repo":"PrefectHQ/fastmcp","slug":"the-resource-decorator-requires-a-uri-use-resou","errorCode":null,"errorMessage":"The @resource decorator requires a URI. Use @resource('uri') instead of @resource","messagePattern":"The @resource decorator requires a URI\\. Use @resource\\('uri'\\) instead of @resource","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/resources/function_resource.py","lineNumber":247,"sourceCode":"    description: str | None = None,\n    icons: list[Icon] | None = None,\n    mime_type: str | None = None,\n    tags: set[str] | None = None,\n    annotations: Annotations | dict[str, Any] | None = None,\n    meta: dict[str, Any] | None = None,\n    auth: AuthCheck | list[AuthCheck] | None = None,\n    security: ResourceSecurity | None | InheritSecurity = INHERIT_SECURITY,\n) -> Callable[[F], F]:\n    \"\"\"Standalone decorator to mark a function as an MCP resource.\n\n    Returns the original function with metadata attached. Register with a server\n    using mcp.add_resource().\n    \"\"\"\n    if isinstance(annotations, dict):\n        annotations = Annotations(**annotations)\n\n    if inspect.isroutine(uri):\n        raise TypeError(\n            \"The @resource decorator requires a URI. \"\n            \"Use @resource('uri') instead of @resource\"\n        )\n\n    def attach_metadata(fn: F) -> F:\n        metadata = ResourceMeta(\n            uri=uri,\n            name=name,\n            version=version,\n            title=title,\n            description=description,\n            icons=icons,\n            tags=tags,\n            mime_type=mime_type,\n            annotations=annotations,\n            meta=meta,\n            auth=auth,\n            security=security,","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/resources/function_resource.py#L229-L265","documentation":"The @resource decorator must be applied with a URI string: @resource('data://x'). Using bare @resource (decorating the function directly, so uri is the function object) is a usage error; inspect.isroutine detects it and raises this TypeError with the corrective hint.","triggerScenarios":"@mcp.resource\\ndef get_data(): ... — i.e. the decorator used without parentheses/arguments, so the 'uri' parameter receives the function itself.","commonSituations":"Copy-paste from plain-Python decorator examples; forgetting the URI argument during refactoring from function registrations to decorators.","solutions":["Add the URI argument: @mcp.resource('data://my-data') above the function","If parameters vary per-call, you may need @mcp.resource('data://{id}') template syntax with the URI including placeholders","Keep parentheses: @resource(...) is a factory, not a direct decorator"],"exampleFix":"// before\n@mcp.resource\ndef get_data(): ...\n// after\n@mcp.resource(\"data://my-data\")\ndef get_data(): ...","handlingStrategy":"type-guard","validationCode":"import inspect\ndef valid_decorator_use(uri):\n    return not inspect.isroutine(uri)  # must be a URI string, not a function","typeGuard":"def is_bare_decorator(resource_arg) -> bool:\n    return inspect.isroutine(resource_arg)","tryCatchPattern":"try:\n    @mcp.resource\n    def fn(): ...\nexcept TypeError as e:\n    raise SyntaxHintError(\"add a URI: @mcp.resource('scheme://path')\") from e","preventionTips":["Never use @mcp.resource without parentheses and a URI string","Use @mcp.resource('scheme://{param}') for templated resources","Code-review decorator stacks: bare @resource always means a missing URI"],"tags":["python","decorator","api-misuse"],"backgroundTag":"decorator-missing-argument","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}