{"record":{"id":"50331245312cdc7c","repo":"rohitg00/ai-engineering-from-scratch","slug":"unknown-tool","errorCode":null,"errorMessage":"unknown tool","messagePattern":"unknown tool","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"certifications/claude/lessons/11-mcp-server-design-and-integration/code/main.py","lineNumber":314,"sourceCode":"            return self._complete(\n                messages=[\n                    {\n                        \"role\": \"user\",\n                        \"content\": {\"type\": \"text\", \"text\": self.prompts[name]},\n                    }\n                ]\n            ), []\n        raise LookupError(f\"Method not found: {method}\")\n\n    def _call_tool(\n        self, params: dict[str, Any], metadata: dict[str, Any]\n    ) -> tuple[dict[str, Any], list[dict[str, Any]]]:\n        name = params[\"name\"]\n        if not isinstance(name, str) or not name:\n            raise ValueError(\"name must be a non-empty string\")\n        tool = self.tools.get(name)\n        if tool is None:\n            raise ValueError(\"unknown tool\")\n        arguments = tool.validate_arguments(params.get(\"arguments\", {}))\n        if name == \"prepare_review\":\n            return self._prepare_review(params, metadata, arguments), []\n\n        token = metadata.get(\"progressToken\")\n        notifications: list[dict[str, Any]] = []\n        if token is not None:\n            if not isinstance(token, (str, int)) or isinstance(token, bool):\n                raise ValueError(\"progressToken must be a string or integer\")\n            notifications = [\n                self._progress(token, 0, 1, \"starting\"),\n                self._progress(token, 1, 1, \"complete\"),\n            ]\n        value = tool.handler(arguments)\n        return self._complete(\n            content=[{\"type\": \"text\", \"text\": json.dumps(value)}], isError=False\n        ), notifications\n","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/rohitg00/ai-engineering-from-scratch/blob/39ea8a1c6d0b61f071226eff7ede4d4105fed820/certifications/claude/lessons/11-mcp-server-design-and-integration/code/main.py#L296-L332","documentation":"The name is a valid non-empty string but self.tools (fixed at server construction) contains no tool with that exact key. The registry is static; the server does not create tools on demand. This is the lookup counterpart of the type check in error 111.","triggerScenarios":"tools/call with a name that is not registered: a stale name from an older server version, wrong casing ('Prepare_Review'), or a tool belonging to a different MCP server.","commonSituations":"Server upgraded and a tool renamed or removed; client caches the tools/list result across restarts; copy-pasting a tool name from documentation for another server.","solutions":["Call tools/list first and use a name from the returned list verbatim","Re-fetch tools/list after any server upgrade instead of caching tool names","Check exact casing, underscores, and hyphens in the name"],"exampleFix":"# before\nparams = {\"name\": \"PrepareReview\"}\n\n# after\nnames = {t[\"name\"] for t in server.exchange(\"tools/list\", {})[\"tools\"]}\nassert \"prepare_review\" in names\nparams = {\"name\": \"prepare_review\"}","handlingStrategy":"validation","validationCode":"tools = server.exchange(\"tools/list\", {})[\"tools\"]\nknown = {t[\"name\"] for t in tools}\nif name not in known:\n    raise ValueError(f\"tool {name!r} not advertised by this server\")\nserver.exchange(\"tools/call\", {\"name\": name, \"arguments\": args})","typeGuard":"def is_known_tool(server, name: str) -> bool:\n    tools = server.exchange(\"tools/list\", {})[\"tools\"]\n    return name in {t[\"name\"] for t in tools}","tryCatchPattern":"try:\n    result = server.exchange(\"tools/call\", params)\nexcept ValueError as exc:\n    if \"unknown tool\" in str(exc):\n        refresh_tool_cache()\n    raise","preventionTips":["Always resolve tool names from a fresh tools/list result","Refresh the tool cache after server upgrades or reconnects","Treat tool names as opaque exact-match identifiers"],"tags":["mcp","tools","registry","lookup"],"backgroundTag":"unknown-tool-name","analyzedSha":"39ea8a1c6d0b61f071226eff7ede4d4105fed820","analyzedAt":"2026-08-26T03:13:46.626Z","schemaVersion":2},"datasetVersion":"2026-08-26T07:17:17.940Z"}