{"record":{"id":"07ca77df150b7948","repo":"rohitg00/ai-engineering-from-scratch","slug":"uri-must-be-a-string","errorCode":null,"errorMessage":"uri must be a string","messagePattern":"uri must be a string","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"certifications/claude/lessons/11-mcp-server-design-and-integration/code/main.py","lineNumber":268,"sourceCode":"                for tool in sorted(self.tools.values(), key=lambda item: item.name)\n            ]\n            return self._complete(\n                tools=tools, ttlMs=300_000, cacheScope=\"public\"\n            ), []\n        if method == \"tools/call\":\n            return self._call_tool(params, metadata)\n        if method == \"resources/list\":\n            resources = [\n                {\"uri\": uri, \"name\": uri.removeprefix(\"config://\")}\n                for uri in sorted(self.resources)\n            ]\n            return self._complete(\n                resources=resources, ttlMs=60_000, cacheScope=\"private\"\n            ), []\n        if method == \"resources/read\":\n            uri = params[\"uri\"]\n            if not isinstance(uri, str):\n                raise ValueError(\"uri must be a string\")\n            if uri not in self.resources:\n                raise ValueError(\"unknown resource\")\n            return self._complete(\n                contents=[\n                    {\n                        \"uri\": uri,\n                        \"mimeType\": \"application/json\",\n                        \"text\": self.resources[uri],\n                    }\n                ],\n                ttlMs=30_000,\n                cacheScope=\"private\",\n            ), []\n        if method == \"prompts/list\":\n            prompts = [\n                {\"name\": name, \"description\": self.prompts[name]}\n                for name in sorted(self.prompts)\n            ]","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/rohitg00/ai-engineering-from-scratch/blob/39ea8a1c6d0b61f071226eff7ede4d4105fed820/certifications/claude/lessons/11-mcp-server-design-and-integration/code/main.py#L250-L286","documentation":"For resources/read, the server does params[\"uri\"] and requires the value to be a str before consulting its resource table. A missing uri raises KeyError instead, so this specific message means uri exists but is the wrong type — number, dict, list, bool, or None. The check happens before the existence check, so a well-typed unknown URI gives error 107 instead.","triggerScenarios":"resources/read with uri set to 42, None, {\"href\": \"...\"}, or a URL object that was never stringified; JSON where the value is an array of URIs.","commonSituations":"Passing an identifier object instead of its string field; config-driven URIs loaded as non-strings; f-string templating bugs producing nested structures.","solutions":["Pass the URI as a plain string: \"study://catalog\"","If the URI comes from structured input, extract the string field first (uri[\"href\"], str(uri))","Validate with isinstance(uri, str) before calling exchange"],"exampleFix":"# before\nserver.exchange(\"resources/read\", {\"uri\": {\"scheme\": \"study\", \"path\": \"/catalog\"}, \"_meta\": meta})\n# after\nserver.exchange(\"resources/read\", {\"uri\": \"study://catalog\", \"_meta\": meta})","handlingStrategy":"type-guard","validationCode":"uri = payload.get(\"uri\")\nif not isinstance(uri, str):\n    raise TypeError(\"uri must be a string\")\npayload[\"uri\"] = uri","typeGuard":"def is_valid_uri_param(params: dict) -> bool:\n    return isinstance(params.get(\"uri\"), str)","tryCatchPattern":null,"preventionTips":["Stringify URIs at the edge where they enter your client","Prefer plain string URIs over structured URL objects in MCP payloads","Validate uri type in the request builder shared by all resources/read calls"],"tags":["mcp","resources","uri","type-validation"],"backgroundTag":"wrong-argument-type","analyzedSha":"39ea8a1c6d0b61f071226eff7ede4d4105fed820","analyzedAt":"2026-08-26T03:13:46.626Z","schemaVersion":2},"datasetVersion":"2026-08-26T07:17:17.940Z"}