{"record":{"id":"222d443501c53545","repo":"PrefectHQ/fastmcp","slug":"provided-resource-uri-is-invalid-str-uri-r","errorCode":null,"errorMessage":"Provided resource URI is invalid: {str(uri)!r}","messagePattern":"Provided resource URI is invalid: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/client/mixins/resources.py","lineNumber":301,"sourceCode":"                A list of content objects.\n\n        Raises:\n            RuntimeError: If called while the client is not connected.\n            MCPError: If the request results in a TimeoutError | JSONRPCError\n        \"\"\"\n        # Merge version into request-level meta (not arguments)\n        request_meta = dict(meta) if meta else {}\n        if version is not None:\n            request_meta[\"fastmcp\"] = {\n                **request_meta.get(\"fastmcp\", {}),\n                \"version\": version,\n            }\n\n        if isinstance(uri, str):\n            try:\n                uri = AnyUrl(uri)  # Ensure AnyUrl\n            except Exception as e:\n                raise ValueError(\n                    f\"Provided resource URI is invalid: {str(uri)!r}\"\n                ) from e\n        result = await self.read_resource_mcp(uri, meta=request_meta or None)\n        return result.contents\n","sourceCodeStart":283,"sourceCodeEnd":306,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/client/mixins/resources.py#L283-L306","documentation":"`ClientResourcesMixin.read_resource()` accepts a URI as `str` or `AnyUrl`; when a string is passed it is coerced via `AnyUrl(uri)`. If that parse fails, the client raises `ValueError` wrapping the original exception, because MCP resources must be addressed by a valid URI. The rejection happens before any network request is sent.","triggerScenarios":"Calling `await client.read_resource(\"not-a-uri\")`, passing a bare path like `\"/data/file.txt\"` without a scheme, a URI with illegal characters or spaces, or an empty string.","commonSituations":"Building URIs by string concatenation and forgetting the scheme prefix; hardcoding URIs with unescaped spaces or special characters; passing a resource name instead of its URI; config files that store relative paths rather than full URIs.","solutions":["Prefix the value with a valid scheme, e.g. `file:///data/file.txt` instead of `/data/file.txt`.","Percent-encode spaces and special characters in the URI (`urllib.parse.quote`).","Fetch the exact URI from `client.list_resources()` / `list_resource_templates()` instead of constructing it by hand.","Validate the string with `AnyUrl(uri)` (pydantic) before calling `read_resource`."],"exampleFix":"// before\ncontents = await client.read_resource(\"/data/config.json\")  # ValueError\n// after\nfrom urllib.parse import quote\nuri = f\"file:///{quote('/data/config.json')}\"\ncontents = await client.read_resource(uri)  # or pass AnyUrl(uri)","handlingStrategy":"validation","validationCode":"from pydantic import AnyUrl\n\ndef is_valid_resource_uri(uri: str) -> bool:\n    try:\n        AnyUrl(uri)\n        return bool(uri.split(\":\", 1)[0])  # non-empty scheme\n    except Exception:\n        return False\n\n# before calling:\n# if not is_valid_resource_uri(candidate):\n#     raise ValueError(f\"Not a valid resource URI: {candidate!r}\")","typeGuard":"from pydantic import AnyUrl\n\ndef as_resource_uri(uri: str) -> AnyUrl | None:\n    try:\n        return AnyUrl(uri)\n    except Exception:\n        return None","tryCatchPattern":"try:\n    contents = await client.read_resource(uri)\nexcept ValueError as e:\n    if \"resource URI is invalid\" in str(e):\n        logger.error(\"Bad resource URI: %s\", e)\n        contents = None  # or look up the real URI via list_resources()\n    else:\n        raise","preventionTips":["Always include a scheme (file://, https://, custom scheme) when building URIs","Percent-encode spaces and reserved characters with urllib.parse.quote","Copy URIs from list_resources()/list_resource_templates() output instead of hand-writing them","Validate with AnyUrl(uri) at config-load time, not at call time"],"tags":["uri","validation","client","resources","valueerror"],"backgroundTag":"invalid-resource-uri","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}