{"record":{"id":"c1e3ecf86078f701","repo":"PrefectHQ/fastmcp","slug":"resource-uri-cannot-be-set-on-resources-the-reso","errorCode":null,"errorMessage":"resource_uri cannot be set on resources — the resource itself is the UI. Use resource_uri on tools to point to a UI resource.","messagePattern":"resource_uri cannot be set on resources — the resource itself is the UI\\. Use resource_uri on tools to point to a UI resource\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/server/server.py","lineNumber":2055,"sourceCode":"                return f\"Weather for {city}: {data}\"\n            ```\n        \"\"\"\n        # Catch incorrect decorator usage early (before any processing)\n        if not isinstance(uri, str):\n            raise TypeError(\n                \"The @resource decorator was used incorrectly. \"\n                \"It requires a URI as the first argument. \"\n                \"Use @resource('uri') instead of @resource\"\n            )\n\n        # Apply default MIME type for ui:// scheme resources\n        mime_type = resolve_ui_mime_type(uri, mime_type)\n\n        # Validate app config for resources — resource_uri and visibility\n        # don't apply since the resource itself is the UI\n        if isinstance(app, AppConfig):\n            if app.resource_uri is not None:\n                raise ValueError(\n                    \"resource_uri cannot be set on resources — \"\n                    \"the resource itself is the UI. \"\n                    \"Use resource_uri on tools to point to a UI resource.\"\n                )\n            if app.visibility is not None:\n                raise ValueError(\n                    \"visibility cannot be set on resources — it only applies to tools.\"\n                )\n\n        # Merge app config into meta[\"ui\"] (wire format) before passing to provider\n        if app is not None and app is not False:\n            meta = dict(meta) if meta else {}\n            if app is True:\n                meta[\"ui\"] = True\n            else:\n                meta[\"ui\"] = app_config_to_meta_dict(app)\n\n        # Delegate to LocalProvider with server-level defaults","sourceCodeStart":2037,"sourceCodeEnd":2073,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/server.py#L2037-L2073","documentation":"The @mcp.resource decorator rejects an AppConfig that sets resource_uri, because a resource already IS the UI surface — resource_uri only makes sense on tools that point at a UI resource. This is a configuration-time validation error (ValueError).","triggerScenarios":"Calling mcp.resource(uri, app=AppConfig(resource_uri=\"ui://...\")) or decorating a resource function with an app config carrying a non-None resource_uri.","commonSituations":"Copy-pasting an AppConfig from a @mcp.tool definition (where resource_uri is valid) onto a @mcp.resource decorator.","solutions":["Remove resource_uri from the AppConfig used on the resource decorator","If you need a UI entry point, define a tool with resource_uri that points at the resource","Use a separate AppConfig instance for tools vs resources"],"exampleFix":"// before\n@mcp.resource(\"ui://panel\", app=AppConfig(resource_uri=\"ui://panel\"))\ndef panel(): ...\n// after\n@mcp.resource(\"ui://panel\")\ndef panel(): ...","handlingStrategy":"validation","validationCode":"if isinstance(app, AppConfig) and app.resource_uri is not None:\n    raise ValueError(\"resource_uri is tool-only; remove it for resources\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep separate AppConfig instances for tools and resources","Never copy tool decorator kwargs onto resource decorators","Remember resources are their own UI surface"],"tags":["python","resources","ui","config"],"backgroundTag":"invalid-app-config-for-component","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}