{"record":{"id":"a2d56af31fe6d5e8","repo":"PrefectHQ/fastmcp","slug":"tool-name-r-not-found","errorCode":null,"errorMessage":"Tool {name!r} not found","messagePattern":"Tool (.+?) not found","errorType":"exception","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/server/providers/local_provider/local_provider.py","lineNumber":247,"sourceCode":"    def remove_tool(self, name: str, version: str | None = None) -> None:\n        \"\"\"Remove tool(s) from this provider's storage.\n\n        Args:\n            name: The tool name.\n            version: If None, removes ALL versions. If specified, removes only that version.\n\n        Raises:\n            KeyError: If no matching tool is found.\n        \"\"\"\n        if version is None:\n            # Remove all versions\n            keys_to_remove = [\n                k\n                for k, c in self._components.items()\n                if isinstance(c, Tool) and c.name == name\n            ]\n            if not keys_to_remove:\n                raise KeyError(f\"Tool {name!r} not found\")\n            for key in keys_to_remove:\n                self._remove_component(key)\n        else:\n            # Remove specific version - key format is \"tool:name@version\"\n            key = f\"{Tool.make_key(name)}@{version}\"\n            if key not in self._components:\n                raise KeyError(f\"Tool {name!r} version {version!r} not found\")\n            self._remove_component(key)\n\n    def remove_resource(self, uri: str, version: str | None = None) -> None:\n        \"\"\"Remove resource(s) from this provider's storage.\n\n        Args:\n            uri: The resource URI.\n            version: If None, removes ALL versions. If specified, removes only that version.\n\n        Raises:\n            KeyError: If no matching resource is found.","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/providers/local_provider/local_provider.py#L229-L265","documentation":"remove_tool(name, version=None) scans LocalProvider storage for Tool components matching the given name; when version is None and no matching Tool exists, it raises KeyError(f\"Tool {name!r} not found\"). The library throws this so callers get a clear signal that removal was a no-op rather than silently succeeding.","triggerScenarios":"Calling provider.remove_tool(\"name\") when no tool with that name was ever added, when it was added to a different provider/server, when it was already removed, or when the name casing/prefix differs from the registered tool name.","commonSituations":"Teardown code removing a tool that failed to register; test fixtures removing tools mounted elsewhere (mounted providers are not local storage); renaming a tool but not updating cleanup code.","solutions":["Check the tool exists first (e.g. via _get_tool or list_tools) before removing","Confirm the tool is registered on this LocalProvider and not a mounted/proxied provider","Catch KeyError to make removal idempotent","Verify exact name spelling and case"],"exampleFix":"// before\nprovider.remove_tool(\"get_weather\")  # KeyError if absent\n// after\nif await provider._get_tool(\"get_weather\") is not None:\n    provider.remove_tool(\"get_weather\")","handlingStrategy":"try-catch","validationCode":"names = {t.name for t in provider._list_tools_sync() if hasattr(provider, '_list_tools_sync')} or await list_tools(provider)\nif \"my_tool\" not in names:\n    return","typeGuard":"def tool_exists(provider, name: str) -> bool:\n    return any(isinstance(c, Tool) and c.name == name\n               for c in provider._components.values())","tryCatchPattern":"try:\n    provider.remove_tool(\"my_tool\")\nexcept KeyError:\n    logger.warning(\"tool my_tool not present; skipping removal\")","preventionTips":["Confirm the tool is registered on this provider, not a mounted one","Keep registration and removal names in a shared constant","Make test/teardown removals idempotent"],"tags":["keyerror","tool","removal","provider"],"backgroundTag":"component-key-not-found","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}